import sys
import math
import torch as th

TEN = th.Tensor

NodesSycamoreN12M14 = [
    [10, 11, 1], [12, 13, 0], [6, 7, 3], [8, 9, 2], [6, 7, 5], [8, 9, 4], [10, 21, 2, 4], [11, 16, 2, 4],
    [12, 16, 3, 5], [13, 22, 3, 5], [17, 19, 0, 6], [14, 15, 0, 7], [14, 15, 1, 8], [18, 20, 1, 9], [17, 18, 11, 12],
    [19, 20, 11, 12], [21, 22, 7, 8], [27, 28, 10, 14], [29, 30, 14, 13], [23, 24, 10, 15], [25, 26, 15, 13],
    [23, 24, 6, 16], [25, 26, 16, 9], [27, 38, 19, 21], [28, 33, 19, 21], [29, 33, 20, 22], [30, 39, 20, 22],
    [34, 36, 17, 23], [31, 32, 17, 24], [31, 32, 18, 25], [35, 37, 18, 26], [34, 35, 28, 29], [36, 37, 28, 29],
    [38, 39, 24, 25], [44, 45, 27, 31], [46, 47, 31, 30], [40, 41, 27, 32], [42, 43, 32, 30], [40, 41, 23, 33],
    [42, 43, 33, 26], [44, 36, 38, 50], [45, 50, 36, 38], [46, 50, 37, 39], [47, 50, 37, 39], [34, 40, 48, 49],
    [48, 49, 34, 41], [48, 49, 35, 42], [48, 49, 35, 43], [44, 45, 46, 47], [44, 45, 46, 47], [40, 41, 42, 43]
]
NodesSycamoreN14M14 = [
    [12, 6, 1], [7, 15, 0], [8, 9, 3], [10, 11, 2], [8, 9, 5], [10, 11, 4], [16, 13, 7, 0], [16, 14, 6, 1],
    [12, 24, 2, 4], [13, 19, 2, 4], [14, 19, 3, 5], [15, 25, 3, 5], [20, 22, 0, 8], [17, 18, 6, 9], [17, 18, 7, 10],
    [21, 23, 1, 11], [26, 27, 6, 7], [20, 21, 13, 14], [22, 23, 13, 14], [24, 25, 9, 10], [32, 26, 12, 17],
    [27, 35, 17, 15], [28, 29, 12, 18], [30, 31, 18, 15], [28, 29, 8, 19], [30, 31, 19, 11], [36, 33, 16, 20],
    [36, 34, 16, 21], [32, 44, 22, 24], [33, 39, 22, 24], [34, 39, 23, 25], [35, 45, 23, 25], [40, 42, 20, 28],
    [37, 38, 26, 29], [37, 38, 27, 30], [41, 43, 21, 31], [46, 47, 26, 27], [40, 41, 33, 34], [42, 43, 33, 34],
    [44, 45, 29, 30], [52, 46, 32, 37], [47, 55, 37, 35], [48, 49, 32, 38], [50, 51, 38, 35], [48, 49, 28, 39],
    [50, 51, 39, 31], [53, 36, 40, 47], [46, 54, 36, 41], [52, 42, 44, 58], [53, 58, 42, 44], [54, 58, 43, 45],
    [55, 58, 43, 45], [40, 48, 56, 57], [56, 57, 46, 49], [56, 57, 47, 50], [56, 57, 41, 51], [52, 53, 54, 55],
    [52, 53, 54, 55], [48, 49, 50, 51]
]

NodesSycamoreN53M12 = [
    [19, 20, 3], [20, 43, 6], [21, 22, 19, 7], [22, 25, 0, 11], [23, 26, 21, 12], [24, 28, 13], [25, 29, 1, 14],
    [26, 30, 2, 15], [27, 31, 23, 55], [28, 32, 36], [29, 33, 24, 16], [30, 34, 3, 17], [31, 35, 4, 58],
    [33, 36, 5, 39], [34, 37, 6, 18], [35, 38, 7, 60], [37, 39, 10, 41], [38, 40, 11, 61], [40, 41, 14, 127],
    [0, 128, 104, 2], [62, 42, 1, 0], [42, 63, 2, 4], [43, 44, 3, 2], [44, 65, 4, 8], [66, 45, 5, 10], [45, 46, 6, 3],
    [46, 47, 7, 4], [47, 69, 8, 51], [70, 48, 9, 5], [48, 49, 10, 6], [49, 50, 11, 7], [50, 51, 12, 8], [74, 52, 9],
    [52, 53, 13, 10], [53, 54, 14, 11], [54, 55, 15, 12], [78, 56, 9, 13], [56, 57, 16, 14], [57, 58, 17, 15],
    [81, 59, 13, 16], [59, 60, 18, 17], [83, 61, 16, 18], [62, 63, 20, 21], [85, 64, 1, 22], [64, 65, 22, 23],
    [66, 67, 24, 25], [67, 68, 25, 26], [68, 69, 26, 27], [70, 71, 28, 29], [71, 72, 29, 30], [72, 73, 30, 31],
    [73, 93, 31, 27], [74, 75, 32, 33], [75, 76, 33, 34], [76, 77, 34, 35], [77, 97, 35, 8], [78, 79, 36, 37],
    [79, 80, 37, 38], [80, 100, 38, 12], [81, 82, 39, 40], [82, 102, 40, 15], [83, 103, 41, 17], [129, 84, 20, 42],
    [84, 106, 42, 21], [85, 86, 43, 44], [86, 109, 44, 23], [133, 87, 24, 45], [87, 88, 45, 46], [88, 89, 46, 47],
    [89, 113, 47, 27], [137, 90, 28, 48], [90, 91, 48, 49], [91, 92, 49, 50], [92, 93, 50, 51], [201, 94, 32, 52],
    [94, 95, 52, 53], [95, 96, 53, 54], [96, 97, 54, 55], [118, 98, 36, 56], [98, 99, 56, 57], [99, 100, 57, 58],
    [122, 101, 39, 59], [101, 102, 59, 60], [125, 103, 41, 61], [105, 104, 62, 63], [107, 105, 43, 64],
    [108, 106, 64, 65], [110, 107, 66, 67], [111, 108, 67, 68], [112, 109, 68, 69], [114, 110, 70, 71],
    [115, 111, 71, 72], [116, 112, 72, 73], [117, 113, 73, 51], [118, 114, 74, 75], [119, 115, 75, 76],
    [120, 116, 76, 77], [121, 117, 77, 55], [122, 119, 78, 79], [123, 120, 79, 80], [124, 121, 80, 58],
    [125, 123, 81, 82], [126, 124, 82, 60], [127, 126, 83, 61], [147, 130, 19, 84], [128, 131, 84, 85],
    [149, 132, 63, 86], [129, 134, 85, 87], [130, 135, 86, 88], [152, 136, 65, 89], [153, 138, 87, 90],
    [131, 139, 88, 91], [132, 140, 89, 92], [69, 93, 196, 200], [133, 141, 90, 94], [134, 142, 91, 95],
    [135, 143, 92, 96], [136, 159, 93, 97], [137, 160, 94, 78], [138, 144, 95, 98], [139, 145, 96, 99],
    [140, 163, 97, 100], [141, 164, 98, 81], [142, 146, 99, 101], [143, 166, 100, 102], [144, 167, 101, 83],
    [145, 168, 102, 103], [146, 169, 103, 18], [170, 148, 19, 105], [171, 150, 62, 107], [147, 151, 104, 108],
    [148, 154, 105, 111], [149, 155, 106, 112], [175, 156, 66, 114], [150, 157, 107, 115], [151, 158, 108, 116],
    [152, 159, 109, 117], [179, 160, 70, 118], [153, 161, 110, 119], [154, 162, 111, 120], [155, 163, 112, 121],
    [156, 164, 114, 122], [157, 165, 115, 123], [158, 166, 116, 124], [161, 167, 119, 125], [162, 168, 120, 126],
    [165, 169, 123, 127], [170, 172, 104, 130], [170, 173, 128, 131], [190, 174, 106, 132], [171, 176, 129, 134],
    [172, 177, 130, 135], [192, 178, 109, 136], [193, 180, 110, 138], [173, 181, 131, 139], [174, 182, 132, 140],
    [175, 183, 133, 141], [176, 184, 134, 142], [177, 185, 135, 143], [178, 204, 136, 117], [179, 205, 137, 118],
    [180, 186, 138, 144], [181, 187, 139, 145], [182, 207, 140, 121], [183, 208, 141, 122], [184, 188, 142, 146],
    [185, 209, 143, 124], [186, 210, 144, 125], [187, 210, 145, 126], [188, 146, 127], [189, 128, 148, 147],
    [189, 129, 150, 191], [190, 191, 147, 151], [191, 194, 148, 154], [192, 195, 149, 155], [193, 197, 133, 156],
    [194, 198, 150, 157], [195, 199, 151, 158], [196, 200, 152, 159], [197, 201, 137, 160], [198, 202, 153, 161],
    [199, 203, 154, 162], [200, 204, 155, 163], [202, 205, 156, 164], [203, 206, 157, 165], [204, 207, 158, 166],
    [206, 208, 161, 167], [207, 209, 162, 168], [209, 210, 165, 169], [171, 170, 190], [189, 172, 149],
    [171, 173, 172, 192], [191, 174, 152], [175, 153, 194], [193, 176, 173, 195], [194, 177, 174, 196], [195, 178, 113],
    [179, 175, 198], [197, 180, 176, 199], [198, 181, 177, 200], [199, 182, 178, 113], [74, 179, 202],
    [201, 183, 180, 203], [202, 184, 181, 204], [203, 185, 182, 159], [160, 183, 206], [205, 186, 184, 207],
    [206, 187, 185, 163], [164, 186, 209], [208, 188, 187, 166], [167, 188, 168]
]
NodesSycamoreN53M14 = [
    [19, 20, 3], [20, 43, 6], [21, 22, 19, 7], [22, 25, 0, 11], [23, 26, 21, 12], [24, 28, 13], [25, 29, 1, 14],
    [26, 30, 2, 15], [27, 31, 23, 55], [28, 32, 36], [29, 33, 24, 16], [30, 34, 3, 17], [31, 35, 4, 58],
    [33, 36, 5, 39], [34, 37, 6, 18], [35, 38, 7, 60], [37, 39, 10, 41], [38, 40, 11, 61], [40, 41, 14, 127],
    [0, 128, 104, 2], [62, 42, 1, 0], [42, 63, 2, 4], [43, 44, 3, 2], [44, 65, 4, 8], [66, 45, 5, 10], [45, 46, 6, 3],
    [46, 47, 7, 4], [47, 69, 8, 51], [70, 48, 9, 5], [48, 49, 10, 6], [49, 50, 11, 7], [50, 51, 12, 8], [74, 52, 9],
    [52, 53, 13, 10], [53, 54, 14, 11], [54, 55, 15, 12], [78, 56, 9, 13], [56, 57, 16, 14], [57, 58, 17, 15],
    [81, 59, 13, 16], [59, 60, 18, 17], [83, 61, 16, 18], [62, 63, 20, 21], [85, 64, 1, 22], [64, 65, 22, 23],
    [66, 67, 24, 25], [67, 68, 25, 26], [68, 69, 26, 27], [70, 71, 28, 29], [71, 72, 29, 30], [72, 73, 30, 31],
    [73, 93, 31, 27], [74, 75, 32, 33], [75, 76, 33, 34], [76, 77, 34, 35], [77, 97, 35, 8], [78, 79, 36, 37],
    [79, 80, 37, 38], [80, 100, 38, 12], [81, 82, 39, 40], [82, 102, 40, 15], [83, 103, 41, 17], [129, 84, 20, 42],
    [84, 106, 42, 21], [85, 86, 43, 44], [86, 109, 44, 23], [133, 87, 24, 45], [87, 88, 45, 46], [88, 89, 46, 47],
    [89, 113, 47, 27], [137, 90, 28, 48], [90, 91, 48, 49], [91, 92, 49, 50], [92, 93, 50, 51], [201, 94, 32, 52],
    [94, 95, 52, 53], [95, 96, 53, 54], [96, 97, 54, 55], [118, 98, 36, 56], [98, 99, 56, 57], [99, 100, 57, 58],
    [122, 101, 39, 59], [101, 102, 59, 60], [125, 103, 41, 61], [105, 104, 62, 63], [107, 105, 43, 64],
    [108, 106, 64, 65], [110, 107, 66, 67], [111, 108, 67, 68], [112, 109, 68, 69], [114, 110, 70, 71],
    [115, 111, 71, 72], [116, 112, 72, 73], [117, 113, 73, 51], [118, 114, 74, 75], [119, 115, 75, 76],
    [120, 116, 76, 77], [121, 117, 77, 55], [122, 119, 78, 79], [123, 120, 79, 80], [124, 121, 80, 58],
    [125, 123, 81, 82], [126, 124, 82, 60], [127, 126, 83, 61], [147, 130, 19, 84], [128, 131, 84, 85],
    [149, 132, 63, 86], [129, 134, 85, 87], [130, 135, 86, 88], [152, 136, 65, 89], [153, 138, 87, 90],
    [131, 139, 88, 91], [132, 140, 89, 92], [69, 93, 196, 236], [133, 141, 90, 94], [134, 142, 91, 95],
    [135, 143, 92, 96], [136, 159, 93, 97], [137, 160, 94, 78], [138, 144, 95, 98], [139, 145, 96, 99],
    [140, 163, 97, 100], [141, 164, 98, 81], [142, 146, 99, 101], [143, 166, 100, 102], [144, 167, 101, 83],
    [145, 168, 102, 103], [146, 169, 103, 18], [170, 148, 19, 105], [171, 150, 62, 107], [147, 151, 104, 108],
    [148, 154, 105, 111], [149, 155, 106, 112], [175, 156, 66, 114], [150, 157, 107, 115], [151, 158, 108, 116],
    [152, 159, 109, 117], [179, 160, 70, 118], [153, 161, 110, 119], [154, 162, 111, 120], [155, 163, 112, 121],
    [156, 164, 114, 122], [157, 165, 115, 123], [158, 166, 116, 124], [161, 167, 119, 125], [162, 168, 120, 126],
    [165, 169, 123, 127], [170, 172, 104, 130], [170, 173, 128, 131], [190, 174, 106, 132], [171, 176, 129, 134],
    [172, 177, 130, 135], [192, 178, 109, 136], [193, 180, 110, 138], [173, 181, 131, 139], [174, 182, 132, 140],
    [175, 183, 133, 141], [176, 184, 134, 142], [177, 185, 135, 143], [178, 240, 136, 117], [179, 205, 137, 118],
    [180, 186, 138, 144], [181, 187, 139, 145], [182, 243, 140, 121], [183, 208, 141, 122], [184, 188, 142, 146],
    [185, 245, 143, 124], [186, 210, 144, 125], [187, 210, 145, 126], [188, 146, 127], [189, 128, 148, 147],
    [189, 227, 129, 150], [190, 191, 147, 151], [191, 194, 148, 154], [192, 195, 149, 155], [193, 197, 133, 156],
    [194, 198, 150, 157], [195, 199, 151, 158], [196, 200, 152, 159], [197, 201, 137, 160], [198, 202, 153, 161],
    [199, 203, 154, 162], [200, 204, 155, 163], [202, 205, 156, 164], [203, 206, 157, 165], [204, 207, 158, 166],
    [206, 208, 161, 167], [207, 209, 162, 168], [209, 210, 165, 169], [225, 211, 171, 170], [211, 226, 172, 149],
    [227, 212, 173, 172], [212, 228, 174, 152], [229, 213, 175, 153], [213, 214, 176, 173], [214, 215, 177, 174],
    [215, 232, 178, 113], [233, 216, 179, 175], [216, 217, 180, 176], [217, 218, 181, 177], [218, 236, 182, 178],
    [237, 219, 74, 179], [219, 220, 183, 180], [220, 221, 184, 181], [221, 240, 185, 182], [241, 222, 160, 183],
    [222, 223, 186, 184], [223, 243, 187, 185], [244, 224, 164, 186], [224, 245, 188, 187], [167, 188, 168],
    [225, 226, 189, 190], [227, 228, 191, 192], [229, 230, 193, 194], [230, 231, 194, 195], [231, 232, 195, 196],
    [233, 234, 197, 198], [234, 235, 198, 199], [235, 236, 199, 200], [237, 238, 201, 202], [238, 239, 202, 203],
    [239, 240, 203, 204], [241, 242, 205, 206], [242, 243, 206, 207], [244, 245, 208, 209], [189, 211, 226],
    [225, 211, 190], [212, 228, 171, 191], [227, 212, 192], [193, 213, 230], [229, 213, 214, 231], [230, 214, 215, 232],
    [231, 215, 196], [197, 216, 234], [233, 216, 217, 235], [234, 217, 218, 236], [235, 218, 200, 113], [201, 219, 238],
    [237, 219, 220, 239], [238, 220, 221, 240], [239, 221, 204, 159], [205, 222, 242], [241, 222, 223, 243],
    [242, 223, 207, 163], [208, 224, 245], [244, 224, 209, 166]
]
NodesSycamoreN53M16 = [
    [19, 20, 3], [20, 43, 6], [21, 22, 19, 7], [22, 25, 0, 11], [23, 26, 21, 12], [24, 28, 13], [25, 29, 1, 14],
    [26, 30, 2, 15], [27, 31, 23, 55], [28, 32, 36], [29, 33, 24, 16], [30, 34, 3, 17], [31, 35, 4, 58],
    [33, 36, 5, 39], [34, 37, 6, 18], [35, 38, 7, 60], [37, 39, 10, 41], [38, 40, 11, 61], [40, 41, 14, 127],
    [0, 128, 104, 2], [62, 42, 1, 0], [42, 63, 2, 4], [43, 44, 3, 2], [44, 65, 4, 8], [66, 45, 5, 10], [45, 46, 6, 3],
    [46, 47, 7, 4], [47, 69, 8, 51], [70, 48, 9, 5], [48, 49, 10, 6], [49, 50, 11, 7], [50, 51, 12, 8], [74, 52, 9],
    [52, 53, 13, 10], [53, 54, 14, 11], [54, 55, 15, 12], [78, 56, 9, 13], [56, 57, 16, 14], [57, 58, 17, 15],
    [81, 59, 13, 16], [59, 60, 18, 17], [83, 61, 16, 18], [62, 63, 20, 21], [85, 64, 1, 22], [64, 65, 22, 23],
    [66, 67, 24, 25], [67, 68, 25, 26], [68, 69, 26, 27], [70, 71, 28, 29], [71, 72, 29, 30], [72, 73, 30, 31],
    [73, 93, 31, 27], [74, 75, 32, 33], [75, 76, 33, 34], [76, 77, 34, 35], [77, 97, 35, 8], [78, 79, 36, 37],
    [79, 80, 37, 38], [80, 100, 38, 12], [81, 82, 39, 40], [82, 102, 40, 15], [83, 103, 41, 17], [129, 84, 20, 42],
    [84, 106, 42, 21], [85, 86, 43, 44], [86, 109, 44, 23], [133, 87, 24, 45], [87, 88, 45, 46], [88, 89, 46, 47],
    [89, 113, 47, 27], [137, 90, 28, 48], [90, 91, 48, 49], [91, 92, 49, 50], [92, 93, 50, 51], [202, 94, 32, 52],
    [94, 95, 52, 53], [95, 96, 53, 54], [96, 97, 54, 55], [118, 98, 36, 56], [98, 99, 56, 57], [99, 100, 57, 58],
    [122, 101, 39, 59], [101, 102, 59, 60], [125, 103, 41, 61], [105, 104, 62, 63], [107, 105, 43, 64],
    [108, 106, 64, 65], [110, 107, 66, 67], [111, 108, 67, 68], [112, 109, 68, 69], [114, 110, 70, 71],
    [115, 111, 71, 72], [116, 112, 72, 73], [117, 113, 73, 51], [118, 114, 74, 75], [119, 115, 75, 76],
    [120, 116, 76, 77], [121, 117, 77, 55], [122, 119, 78, 79], [123, 120, 79, 80], [124, 121, 80, 58],
    [125, 123, 81, 82], [126, 124, 82, 60], [127, 126, 83, 61], [147, 130, 19, 84], [128, 131, 84, 85],
    [149, 132, 63, 86], [129, 134, 85, 87], [130, 135, 86, 88], [152, 136, 65, 89], [153, 138, 87, 90],
    [131, 139, 88, 91], [132, 140, 89, 92], [69, 93, 197, 221], [133, 141, 90, 94], [134, 142, 91, 95],
    [135, 143, 92, 96], [136, 159, 93, 97], [137, 160, 94, 78], [138, 144, 95, 98], [139, 145, 96, 99],
    [140, 163, 97, 100], [141, 164, 98, 81], [142, 146, 99, 101], [143, 166, 100, 102], [144, 167, 101, 83],
    [145, 168, 102, 103], [146, 169, 103, 18], [170, 148, 19, 105], [171, 150, 62, 107], [147, 151, 104, 108],
    [148, 154, 105, 111], [149, 155, 106, 112], [175, 156, 66, 114], [150, 157, 107, 115], [151, 158, 108, 116],
    [152, 159, 109, 117], [179, 160, 70, 118], [153, 161, 110, 119], [154, 162, 111, 120], [155, 163, 112, 121],
    [156, 164, 114, 122], [157, 165, 115, 123], [158, 166, 116, 124], [161, 167, 119, 125], [162, 168, 120, 126],
    [165, 169, 123, 127], [189, 172, 104, 130], [170, 173, 128, 131], [191, 174, 106, 132], [171, 176, 129, 134],
    [172, 177, 130, 135], [193, 178, 109, 136], [194, 180, 110, 138], [173, 181, 131, 139], [174, 182, 132, 140],
    [175, 183, 133, 141], [176, 184, 134, 142], [177, 185, 135, 143], [178, 225, 136, 117], [179, 206, 137, 118],
    [180, 186, 138, 144], [181, 187, 139, 145], [182, 228, 140, 121], [183, 209, 141, 122], [184, 188, 142, 146],
    [185, 230, 143, 124], [186, 211, 144, 125], [187, 231, 145, 126], [188, 296, 146, 127], [189, 190, 128, 148],
    [190, 213, 129, 150], [191, 192, 147, 151], [192, 195, 148, 154], [193, 196, 149, 155], [194, 198, 133, 156],
    [195, 199, 150, 157], [196, 200, 151, 158], [197, 201, 152, 159], [198, 202, 137, 160], [199, 203, 153, 161],
    [200, 204, 154, 162], [201, 205, 155, 163], [203, 206, 156, 164], [204, 207, 157, 165], [205, 208, 158, 166],
    [207, 209, 161, 167], [208, 210, 162, 168], [210, 211, 165, 169], [170, 147, 274, 275], [232, 212, 171, 170],
    [212, 233, 172, 149], [213, 214, 173, 172], [214, 235, 174, 152], [236, 215, 175, 153], [215, 216, 176, 173],
    [216, 217, 177, 174], [217, 239, 178, 113], [240, 218, 179, 175], [218, 219, 180, 176], [219, 220, 181, 177],
    [220, 221, 182, 178], [244, 222, 74, 179], [222, 223, 183, 180], [223, 224, 184, 181], [224, 225, 185, 182],
    [248, 226, 160, 183], [226, 227, 186, 184], [227, 228, 187, 185], [251, 229, 164, 186], [229, 230, 188, 187],
    [253, 231, 167, 188], [232, 233, 190, 191], [255, 234, 171, 192], [234, 235, 192, 193], [236, 237, 194, 195],
    [237, 238, 195, 196], [238, 239, 196, 197], [240, 241, 198, 199], [241, 242, 199, 200], [242, 243, 200, 201],
    [243, 263, 201, 113], [244, 245, 202, 203], [245, 246, 203, 204], [246, 247, 204, 205], [247, 267, 205, 159],
    [248, 249, 206, 207], [249, 250, 207, 208], [250, 270, 208, 163], [251, 252, 209, 210], [252, 272, 210, 166],
    [253, 273, 211, 168], [254, 190, 212, 277], [254, 276, 212, 191], [255, 256, 213, 214], [256, 279, 214, 193],
    [257, 194, 215, 283], [257, 258, 215, 216], [258, 259, 216, 217], [259, 217, 197, 263], [260, 198, 218, 287],
    [260, 261, 218, 219], [261, 262, 219, 220], [262, 263, 220, 221], [264, 202, 222], [264, 265, 222, 223],
    [265, 266, 223, 224], [266, 267, 224, 225], [287, 268, 206, 226], [268, 269, 226, 227], [269, 270, 227, 228],
    [291, 271, 209, 229], [271, 272, 229, 230], [294, 273, 211, 231], [275, 274, 232, 233], [277, 275, 213, 234],
    [278, 276, 234, 235], [280, 277, 236, 237], [281, 278, 237, 238], [282, 279, 238, 239], [283, 280, 240, 241],
    [284, 281, 241, 242], [285, 282, 242, 243], [286, 239, 243, 221], [287, 283, 244, 245], [288, 284, 245, 246],
    [289, 285, 246, 247], [290, 286, 247, 225], [291, 288, 248, 249], [292, 289, 249, 250], [293, 290, 250, 228],
    [294, 292, 251, 252], [295, 293, 252, 230], [296, 295, 253, 231], [189, 254, 278], [189, 254, 255, 281],
    [233, 256, 282], [232, 255, 257, 284], [274, 256, 258, 285], [235, 259, 286], [257, 260, 288], [275, 258, 261, 289],
    [276, 259, 262, 290], [236, 260, 264, 291], [277, 261, 265, 292], [278, 262, 266, 293], [279, 263, 267],
    [240, 264, 248], [280, 265, 268, 294], [281, 266, 269, 295], [282, 267, 270], [283, 268, 251], [284, 269, 271, 296],
    [285, 270, 272], [288, 271, 253], [289, 272, 273], [292, 273, 169]
]
NodesSycamoreN53M18 = [
    [19, 20, 3], [20, 43, 6], [21, 22, 19, 7], [22, 25, 0, 11], [23, 26, 21, 12], [24, 28, 13], [25, 29, 1, 14],
    [26, 30, 2, 15], [27, 31, 23, 55], [28, 32, 36], [29, 33, 24, 16], [30, 34, 3, 17], [31, 35, 4, 58],
    [33, 36, 5, 39], [34, 37, 6, 18], [35, 38, 7, 60], [37, 39, 10, 41], [38, 40, 11, 61], [40, 41, 14, 127],
    [0, 128, 104, 2], [62, 42, 1, 0], [42, 63, 2, 4], [43, 44, 3, 2], [44, 65, 4, 8], [66, 45, 5, 10], [45, 46, 6, 3],
    [46, 47, 7, 4], [47, 69, 8, 51], [70, 48, 9, 5], [48, 49, 10, 6], [49, 50, 11, 7], [50, 51, 12, 8], [74, 52, 9],
    [52, 53, 13, 10], [53, 54, 14, 11], [54, 55, 15, 12], [78, 56, 9, 13], [56, 57, 16, 14], [57, 58, 17, 15],
    [81, 59, 13, 16], [59, 60, 18, 17], [83, 61, 16, 18], [62, 63, 20, 21], [85, 64, 1, 22], [64, 65, 22, 23],
    [66, 67, 24, 25], [67, 68, 25, 26], [68, 69, 26, 27], [70, 71, 28, 29], [71, 72, 29, 30], [72, 73, 30, 31],
    [73, 93, 31, 27], [74, 75, 32, 33], [75, 76, 33, 34], [76, 77, 34, 35], [77, 97, 35, 8], [78, 79, 36, 37],
    [79, 80, 37, 38], [80, 100, 38, 12], [81, 82, 39, 40], [82, 102, 40, 15], [83, 103, 41, 17], [129, 84, 20, 42],
    [84, 106, 42, 21], [85, 86, 43, 44], [86, 109, 44, 23], [133, 87, 24, 45], [87, 88, 45, 46], [88, 89, 46, 47],
    [89, 113, 47, 27], [137, 90, 28, 48], [90, 91, 48, 49], [91, 92, 49, 50], [92, 93, 50, 51], [202, 94, 32, 52],
    [94, 95, 52, 53], [95, 96, 53, 54], [96, 97, 54, 55], [118, 98, 36, 56], [98, 99, 56, 57], [99, 100, 57, 58],
    [122, 101, 39, 59], [101, 102, 59, 60], [125, 103, 41, 61], [105, 104, 62, 63], [107, 105, 43, 64],
    [108, 106, 64, 65], [110, 107, 66, 67], [111, 108, 67, 68], [112, 109, 68, 69], [114, 110, 70, 71],
    [115, 111, 71, 72], [116, 112, 72, 73], [117, 113, 73, 51], [118, 114, 74, 75], [119, 115, 75, 76],
    [120, 116, 76, 77], [121, 117, 77, 55], [122, 119, 78, 79], [123, 120, 79, 80], [124, 121, 80, 58],
    [125, 123, 81, 82], [126, 124, 82, 60], [127, 126, 83, 61], [147, 130, 19, 84], [128, 131, 84, 85],
    [149, 132, 63, 86], [129, 134, 85, 87], [130, 135, 86, 88], [152, 136, 65, 89], [153, 138, 87, 90],
    [131, 139, 88, 91], [132, 140, 89, 92], [69, 93, 197, 221], [133, 141, 90, 94], [134, 142, 91, 95],
    [135, 143, 92, 96], [136, 159, 93, 97], [137, 160, 94, 78], [138, 144, 95, 98], [139, 145, 96, 99],
    [140, 163, 97, 100], [141, 164, 98, 81], [142, 146, 99, 101], [143, 166, 100, 102], [144, 167, 101, 83],
    [145, 168, 102, 103], [146, 169, 103, 18], [170, 148, 19, 105], [171, 150, 62, 107], [147, 151, 104, 108],
    [148, 154, 105, 111], [149, 155, 106, 112], [175, 156, 66, 114], [150, 157, 107, 115], [151, 158, 108, 116],
    [152, 159, 109, 117], [179, 160, 70, 118], [153, 161, 110, 119], [154, 162, 111, 120], [155, 163, 112, 121],
    [156, 164, 114, 122], [157, 165, 115, 123], [158, 166, 116, 124], [161, 167, 119, 125], [162, 168, 120, 126],
    [165, 169, 123, 127], [189, 172, 104, 130], [170, 173, 128, 131], [191, 174, 106, 132], [171, 176, 129, 134],
    [172, 177, 130, 135], [193, 178, 109, 136], [194, 180, 110, 138], [173, 181, 131, 139], [174, 182, 132, 140],
    [175, 183, 133, 141], [176, 184, 134, 142], [177, 185, 135, 143], [178, 225, 136, 117], [179, 206, 137, 118],
    [180, 186, 138, 144], [181, 187, 139, 145], [182, 228, 140, 121], [183, 209, 141, 122], [184, 188, 142, 146],
    [185, 230, 143, 124], [186, 211, 144, 125], [187, 231, 145, 126], [188, 296, 146, 127], [189, 190, 128, 148],
    [190, 213, 129, 150], [191, 192, 147, 151], [192, 195, 148, 154], [193, 196, 149, 155], [194, 198, 133, 156],
    [195, 199, 150, 157], [196, 200, 151, 158], [197, 201, 152, 159], [198, 202, 137, 160], [199, 203, 153, 161],
    [200, 204, 154, 162], [201, 205, 155, 163], [203, 206, 156, 164], [204, 207, 157, 165], [205, 208, 158, 166],
    [207, 209, 161, 167], [208, 210, 162, 168], [210, 211, 165, 169], [170, 147, 313, 274], [232, 212, 171, 170],
    [212, 233, 172, 149], [213, 214, 173, 172], [214, 235, 174, 152], [236, 215, 175, 153], [215, 216, 176, 173],
    [216, 217, 177, 174], [217, 239, 178, 113], [240, 218, 179, 175], [218, 219, 180, 176], [219, 220, 181, 177],
    [220, 221, 182, 178], [244, 222, 74, 179], [222, 223, 183, 180], [223, 224, 184, 181], [224, 225, 185, 182],
    [248, 226, 160, 183], [226, 227, 186, 184], [227, 228, 187, 185], [251, 229, 164, 186], [229, 230, 188, 187],
    [253, 231, 167, 188], [232, 233, 190, 191], [255, 234, 171, 192], [234, 235, 192, 193], [236, 237, 194, 195],
    [237, 238, 195, 196], [238, 239, 196, 197], [240, 241, 198, 199], [241, 242, 199, 200], [242, 243, 200, 201],
    [243, 263, 201, 113], [244, 245, 202, 203], [245, 246, 203, 204], [246, 247, 204, 205], [247, 267, 205, 159],
    [248, 249, 206, 207], [249, 250, 207, 208], [250, 270, 208, 163], [251, 252, 209, 210], [252, 272, 210, 166],
    [253, 273, 211, 168], [315, 254, 190, 212], [254, 276, 212, 191], [255, 256, 213, 214], [256, 279, 214, 193],
    [321, 257, 194, 215], [257, 258, 215, 216], [258, 259, 216, 217], [259, 217, 197, 263], [287, 260, 198, 218],
    [260, 261, 218, 219], [261, 262, 219, 220], [262, 263, 220, 221], [264, 202, 222], [264, 265, 222, 223],
    [265, 266, 223, 224], [266, 267, 224, 225], [287, 268, 206, 226], [268, 269, 226, 227], [269, 270, 227, 228],
    [291, 271, 209, 229], [271, 272, 229, 230], [294, 273, 211, 231], [275, 274, 232, 233], [277, 275, 213, 234],
    [278, 276, 234, 235], [280, 277, 236, 237], [281, 278, 237, 238], [282, 279, 238, 239], [283, 280, 240, 241],
    [284, 281, 241, 242], [285, 282, 242, 243], [286, 239, 243, 221], [287, 283, 244, 245], [288, 284, 245, 246],
    [289, 285, 246, 247], [290, 286, 247, 225], [291, 288, 248, 249], [292, 289, 249, 250], [293, 290, 250, 228],
    [294, 292, 251, 252], [295, 293, 252, 230], [296, 295, 253, 231], [312, 297, 189, 254], [313, 298, 254, 255],
    [314, 299, 233, 256], [315, 300, 255, 257], [297, 301, 256, 258], [317, 302, 235, 259], [318, 303, 257, 260],
    [298, 304, 258, 261], [299, 305, 259, 262], [321, 306, 260, 264], [300, 307, 261, 265], [301, 308, 262, 266],
    [302, 324, 263, 267], [264, 248, 240], [303, 309, 265, 268], [304, 310, 266, 269], [305, 327, 267, 270],
    [306, 328, 268, 251], [307, 311, 269, 271], [308, 330, 270, 272], [309, 331, 271, 253], [310, 332, 272, 273],
    [311, 333, 273, 169], [312, 316, 274, 278], [313, 319, 275, 281], [314, 320, 276, 282], [315, 322, 277, 284],
    [316, 323, 278, 285], [317, 324, 279, 286], [318, 325, 280, 288], [319, 326, 281, 289], [320, 327, 282, 290],
    [321, 328, 283, 291], [322, 329, 284, 292], [323, 330, 285, 293], [325, 331, 288, 294], [326, 332, 289, 295],
    [329, 333, 292, 296], [274, 297, 316], [298, 319, 189, 275], [276, 299, 320], [300, 322, 232, 277],
    [312, 297, 301, 323], [279, 302, 324], [280, 303, 325], [313, 298, 304, 326], [314, 299, 305, 327],
    [306, 328, 236, 283], [315, 300, 307, 329], [316, 301, 308, 330], [317, 302, 286], [318, 303, 309, 331],
    [319, 304, 310, 332], [320, 305, 290], [321, 306, 291], [322, 307, 311, 333], [323, 308, 293], [325, 309, 294],
    [326, 310, 295], [329, 311, 296]
]
NodesSycamoreN53M20 = [
    [19, 20, 3], [20, 43, 6], [21, 22, 19, 7], [22, 25, 0, 11], [23, 26, 21, 12], [24, 28, 13], [25, 29, 1, 14],
    [26, 30, 2, 15], [27, 31, 23, 55], [28, 32, 36], [29, 33, 24, 16], [30, 34, 3, 17], [31, 35, 4, 58],
    [33, 36, 5, 39], [34, 37, 6, 18], [35, 38, 7, 60], [37, 39, 10, 41], [38, 40, 11, 61], [40, 41, 14, 127],
    [0, 128, 104, 2], [62, 42, 1, 0], [42, 63, 2, 4], [43, 44, 3, 2], [44, 65, 4, 8], [66, 45, 5, 10], [45, 46, 6, 3],
    [46, 47, 7, 4], [47, 69, 8, 51], [70, 48, 9, 5], [48, 49, 10, 6], [49, 50, 11, 7], [50, 51, 12, 8], [74, 52, 9],
    [52, 53, 13, 10], [53, 54, 14, 11], [54, 55, 15, 12], [78, 56, 9, 13], [56, 57, 16, 14], [57, 58, 17, 15],
    [81, 59, 13, 16], [59, 60, 18, 17], [83, 61, 16, 18], [62, 63, 20, 21], [85, 64, 1, 22], [64, 65, 22, 23],
    [66, 67, 24, 25], [67, 68, 25, 26], [68, 69, 26, 27], [70, 71, 28, 29], [71, 72, 29, 30], [72, 73, 30, 31],
    [73, 93, 31, 27], [74, 75, 32, 33], [75, 76, 33, 34], [76, 77, 34, 35], [77, 97, 35, 8], [78, 79, 36, 37],
    [79, 80, 37, 38], [80, 100, 38, 12], [81, 82, 39, 40], [82, 102, 40, 15], [83, 103, 41, 17], [129, 84, 20, 42],
    [84, 106, 42, 21], [85, 86, 43, 44], [86, 109, 44, 23], [133, 87, 24, 45], [87, 88, 45, 46], [88, 89, 46, 47],
    [89, 113, 47, 27], [137, 90, 28, 48], [90, 91, 48, 49], [91, 92, 49, 50], [92, 93, 50, 51], [202, 94, 32, 52],
    [94, 95, 52, 53], [95, 96, 53, 54], [96, 97, 54, 55], [118, 98, 36, 56], [98, 99, 56, 57], [99, 100, 57, 58],
    [122, 101, 39, 59], [101, 102, 59, 60], [125, 103, 41, 61], [105, 104, 62, 63], [107, 105, 43, 64],
    [108, 106, 64, 65], [110, 107, 66, 67], [111, 108, 67, 68], [112, 109, 68, 69], [114, 110, 70, 71],
    [115, 111, 71, 72], [116, 112, 72, 73], [117, 113, 73, 51], [118, 114, 74, 75], [119, 115, 75, 76],
    [120, 116, 76, 77], [121, 117, 77, 55], [122, 119, 78, 79], [123, 120, 79, 80], [124, 121, 80, 58],
    [125, 123, 81, 82], [126, 124, 82, 60], [127, 126, 83, 61], [147, 130, 19, 84], [128, 131, 84, 85],
    [149, 132, 63, 86], [129, 134, 85, 87], [130, 135, 86, 88], [152, 136, 65, 89], [153, 138, 87, 90],
    [131, 139, 88, 91], [132, 140, 89, 92], [69, 93, 197, 221], [133, 141, 90, 94], [134, 142, 91, 95],
    [135, 143, 92, 96], [136, 159, 93, 97], [137, 160, 94, 78], [138, 144, 95, 98], [139, 145, 96, 99],
    [140, 163, 97, 100], [141, 164, 98, 81], [142, 146, 99, 101], [143, 166, 100, 102], [144, 167, 101, 83],
    [145, 168, 102, 103], [146, 169, 103, 18], [170, 148, 19, 105], [171, 150, 62, 107], [147, 151, 104, 108],
    [148, 154, 105, 111], [149, 155, 106, 112], [175, 156, 66, 114], [150, 157, 107, 115], [151, 158, 108, 116],
    [152, 159, 109, 117], [179, 160, 70, 118], [153, 161, 110, 119], [154, 162, 111, 120], [155, 163, 112, 121],
    [156, 164, 114, 122], [157, 165, 115, 123], [158, 166, 116, 124], [161, 167, 119, 125], [162, 168, 120, 126],
    [165, 169, 123, 127], [189, 172, 104, 130], [170, 173, 128, 131], [191, 174, 106, 132], [171, 176, 129, 134],
    [172, 177, 130, 135], [193, 178, 109, 136], [194, 180, 110, 138], [173, 181, 131, 139], [174, 182, 132, 140],
    [175, 183, 133, 141], [176, 184, 134, 142], [177, 185, 135, 143], [178, 225, 136, 117], [179, 206, 137, 118],
    [180, 186, 138, 144], [181, 187, 139, 145], [182, 228, 140, 121], [183, 209, 141, 122], [184, 188, 142, 146],
    [185, 230, 143, 124], [186, 211, 144, 125], [187, 231, 145, 126], [188, 297, 146, 127], [189, 190, 128, 148],
    [190, 213, 129, 150], [191, 192, 147, 151], [192, 195, 148, 154], [193, 196, 149, 155], [194, 198, 133, 156],
    [195, 199, 150, 157], [196, 200, 151, 158], [197, 201, 152, 159], [198, 202, 137, 160], [199, 203, 153, 161],
    [200, 204, 154, 162], [201, 205, 155, 163], [203, 206, 156, 164], [204, 207, 157, 165], [205, 208, 158, 166],
    [207, 209, 161, 167], [208, 210, 162, 168], [210, 211, 165, 169], [170, 147, 298, 274], [232, 212, 171, 170],
    [212, 233, 172, 149], [213, 214, 173, 172], [214, 235, 174, 152], [236, 215, 175, 153], [215, 216, 176, 173],
    [216, 217, 177, 174], [217, 239, 178, 113], [240, 218, 179, 175], [218, 219, 180, 176], [219, 220, 181, 177],
    [220, 221, 182, 178], [244, 222, 74, 179], [222, 223, 183, 180], [223, 224, 184, 181], [224, 225, 185, 182],
    [248, 226, 160, 183], [226, 227, 186, 184], [227, 228, 187, 185], [251, 229, 164, 186], [229, 230, 188, 187],
    [253, 231, 167, 188], [232, 233, 190, 191], [255, 234, 171, 192], [234, 235, 192, 193], [236, 237, 194, 195],
    [237, 238, 195, 196], [238, 239, 196, 197], [240, 241, 198, 199], [241, 242, 199, 200], [242, 243, 200, 201],
    [243, 263, 201, 113], [244, 245, 202, 203], [245, 246, 203, 204], [246, 247, 204, 205], [247, 267, 205, 159],
    [248, 249, 206, 207], [249, 250, 207, 208], [250, 270, 208, 163], [251, 252, 209, 210], [252, 272, 210, 166],
    [253, 273, 211, 168], [299, 254, 190, 212], [254, 276, 212, 191], [255, 256, 213, 214], [256, 279, 214, 193],
    [303, 257, 194, 215], [257, 258, 215, 216], [258, 259, 216, 217], [259, 283, 217, 197], [307, 260, 198, 218],
    [260, 261, 218, 219], [261, 262, 219, 220], [262, 263, 220, 221], [371, 264, 202, 222], [264, 265, 222, 223],
    [265, 266, 223, 224], [266, 267, 224, 225], [288, 268, 206, 226], [268, 269, 226, 227], [269, 270, 227, 228],
    [292, 271, 209, 229], [271, 272, 229, 230], [295, 273, 211, 231], [275, 274, 232, 233], [277, 275, 213, 234],
    [278, 276, 234, 235], [280, 277, 236, 237], [281, 278, 237, 238], [282, 279, 238, 239], [284, 280, 240, 241],
    [285, 281, 241, 242], [286, 282, 242, 243], [287, 283, 243, 221], [288, 284, 244, 245], [289, 285, 245, 246],
    [290, 286, 246, 247], [291, 287, 247, 225], [292, 289, 248, 249], [293, 290, 249, 250], [294, 291, 250, 228],
    [295, 293, 251, 252], [296, 294, 252, 230], [297, 296, 253, 231], [317, 300, 189, 254], [298, 301, 254, 255],
    [319, 302, 233, 256], [299, 304, 255, 257], [300, 305, 256, 258], [322, 306, 235, 259], [323, 308, 257, 260],
    [301, 309, 258, 261], [302, 310, 259, 262], [239, 263, 366, 370], [303, 311, 260, 264], [304, 312, 261, 265],
    [305, 313, 262, 266], [306, 329, 263, 267], [307, 330, 264, 248], [308, 314, 265, 268], [309, 315, 266, 269],
    [310, 333, 267, 270], [311, 334, 268, 251], [312, 316, 269, 271], [313, 336, 270, 272], [314, 337, 271, 253],
    [315, 338, 272, 273], [316, 339, 273, 169], [340, 318, 189, 275], [341, 320, 232, 277], [317, 321, 274, 278],
    [318, 324, 275, 281], [319, 325, 276, 282], [345, 326, 236, 284], [320, 327, 277, 285], [321, 328, 278, 286],
    [322, 329, 279, 287], [349, 330, 240, 288], [323, 331, 280, 289], [324, 332, 281, 290], [325, 333, 282, 291],
    [326, 334, 284, 292], [327, 335, 285, 293], [328, 336, 286, 294], [331, 337, 289, 295], [332, 338, 290, 296],
    [335, 339, 293, 297], [340, 342, 274, 300], [340, 343, 298, 301], [360, 344, 276, 302], [341, 346, 299, 304],
    [342, 347, 300, 305], [362, 348, 279, 306], [363, 350, 280, 308], [343, 351, 301, 309], [344, 352, 302, 310],
    [345, 353, 303, 311], [346, 354, 304, 312], [347, 355, 305, 313], [348, 374, 306, 287], [349, 375, 307, 288],
    [350, 356, 308, 314], [351, 357, 309, 315], [352, 377, 310, 291], [353, 378, 311, 292], [354, 358, 312, 316],
    [355, 379, 313, 294], [356, 380, 314, 295], [357, 380, 315, 296], [358, 316, 297], [359, 298, 318, 317],
    [359, 299, 320, 361], [360, 361, 317, 321], [361, 364, 318, 324], [362, 365, 319, 325], [363, 367, 303, 326],
    [364, 368, 320, 327], [365, 369, 321, 328], [366, 370, 322, 329], [367, 371, 307, 330], [368, 372, 323, 331],
    [369, 373, 324, 332], [370, 374, 325, 333], [372, 375, 326, 334], [373, 376, 327, 335], [374, 377, 328, 336],
    [376, 378, 331, 337], [377, 379, 332, 338], [379, 380, 335, 339], [341, 340, 360], [359, 342, 319],
    [341, 343, 342, 362], [361, 344, 322], [345, 323, 364], [363, 346, 343, 365], [364, 347, 344, 366], [365, 348, 283],
    [349, 345, 368], [367, 350, 346, 369], [368, 351, 347, 370], [369, 352, 348, 283], [244, 349, 372],
    [371, 353, 350, 373], [372, 354, 351, 374], [373, 355, 352, 329], [330, 353, 376], [375, 356, 354, 377],
    [376, 357, 355, 333], [334, 356, 379], [378, 358, 357, 336], [337, 358, 338]
]

Node2sSycamoreN53N20Test1 = [
    (32, 9), (360, 359), (362, 322), (19, 0), (364, 363), (43, 1), (371, 349), (339, 316), (316, 297), (378, 334),
    (28, 5), (380, 337), (368, 367), (376, 375), (366, 365), (42, 20), (20, 62), (167, 144), (144, 125), (66, 45),
    (45, 24), (248, 206), (261, 242), (206, 226), (361, 341), (118, 78), (293, 271), (231, 168), (340, 318), (318, 298),
    (96, 77), (155, 140), (185, 158), (276, 233), (317, 274), (111, 88), (274, 300), (44, 22), (369, 347), (212, 190),
    (190, 232), (65, 23), (157, 134), (247, 225), (214, 193), (126, 103), (225, 267), (193, 235), (220, 201), (87, 67),
    (244, 202), (202, 222), (251, 229), (229, 209), (333, 291), (291, 310), (17, 11), (25, 6), (319, 302), (326, 311),
    (275, 254), (303, 284), (315, 296), (296, 338), (238, 217), (35, 12), (100, 80), (80, 58), (196, 177), (171, 129),
    (129, 150), (266, 246), (240, 198), (237, 216), (198, 218), (26, 7), (245, 223), (255, 213), (213, 234), (281, 258),
    (81, 59), (59, 39), (199, 176), (170, 128), (128, 148), (324, 301), (114, 90), (138, 119), (115, 91), (98, 79),
    (9, 52), (359, 342), (354, 335), (9, 74), (352, 325), (175, 133), (133, 156), (208, 187), (68, 46), (51, 31),
    (169, 146), (146, 127), (355, 328), (162, 145), (49, 30), (188, 165), (94, 75), (143, 124), (124, 166), (280, 260),
    (370, 283), (137, 70), (236, 215), (215, 194), (152, 136), (136, 109), (228, 163), (221, 113), (105, 84),
    (178, 159), (174, 149), (350, 331), (294, 272), (153, 110), (305, 278), (320, 304), (147, 130), (282, 262),
    (130, 104), (192, 173), (141, 122), (122, 164), (269, 249), (379, 358), (224, 204), (83, 61), (61, 41), (270, 250),
    (112, 92), (93, 73), (38, 15), (180, 161), (313, 286), (179, 160), (332, 309), (82, 60), (60, 102), (295, 253),
    (69, 47), (47, 27), (288, 264), (56, 36), (289, 265), (312, 285), (277, 257), (85, 64), (154, 139), (123, 101),
    (348, 329), (207, 184), (33, 10), (37, 16), (72, 50), (330, 307), (55, 8), (106, 86), (135, 108), (259, 239),
    (203, 183), (230, 210), (71, 48), (373, 351), (205, 182), (117, 97), (372, 353), (53, 34), (95, 76), (219, 200),
    (21, 4), (323, 308), (307, 349), (263, 243), (191, 172), (40, 18), (120, 99), (346, 327), (306, 287), (377, 357),
    (64, 1), (334, 292), (363, 343), (5, 13), (322, 279), (297, 273), (337, 356), (124, 158), (36, 78), (365, 344),
    (73, 31), (284, 311), (284, 345), (239, 217), (217, 197), (165, 127), (250, 163), (0, 2), (308, 331), (41, 103),
    (23, 22), (159, 109), (67, 24), (302, 233), (243, 113), (327, 304), (50, 30), (287, 329), (58, 121), (325, 291),
    (160, 70), (271, 252), (110, 119), (75, 9), (342, 341), (16, 57), (77, 54), (145, 181), (84, 131), (190, 299),
    (6, 14), (20, 63), (86, 132), (287, 279), (168, 211), (173, 195), (129, 107), (249, 227), (309, 290), (298, 189),
    (104, 151), (351, 374), (91, 142), (108, 116), (46, 89), (278, 321), (193, 256), (242, 241), (265, 268), (253, 314),
    (286, 336), (48, 29), (11, 3), (184, 186), (347, 367), (335, 375), (145, 139), (308, 260), (91, 134), (307, 264),
    (84, 128), (54, 76), (252, 209), (36, 79), (104, 172), (286, 272), (193, 213), (110, 161), (290, 296), (113, 201),
    (304, 285), (109, 97), (60, 15), (189, 274), (241, 200), (20, 4), (46, 27), (92, 140), (223, 246), (176, 198),
    (257, 194), (122, 90), (99, 101), (182, 204), (258, 216), (86, 149), (357, 358), (8, 12), (183, 206), (210, 187),
    (344, 283), (34, 10), (264, 202), (284, 292), (253, 337), (18, 39), (301, 254), (110, 125), (182, 225), (30, 31),
    (27, 7), (24, 133), (351, 353), (22, 1), (197, 262), (108, 124), (227, 163), (29, 5), (168, 273), (347, 328),
    (86, 92), (4, 0), (341, 343), (36, 70), (283, 279), (91, 88), (10, 9), (104, 177), (189, 278), (223, 265), (6, 16),
    (190, 233), (357, 335), (184, 127), (193, 173), (3, 41), (8, 54), (99, 139), (97, 58), (200, 113), (18, 15),
    (187, 209), (253, 260), (1, 107), (216, 194), (0, 84), (183, 90), (182, 291), (189, 341), (351, 284), (254, 290),
    (328, 272), (7, 30), (202, 176), (36, 5), (104, 108), (24, 110), (187, 163), (335, 285), (15, 3), (279, 197),
    (6, 9), (194, 173), (253, 168), (0, 1), (182, 223), (127, 88), (58, 8), (104, 86), (189, 190), (6, 5), (197, 113),
    (24, 90), (272, 284), (3, 99), (189, 254), (8, 7), (168, 285), (24, 5), (182, 176), (88, 163), (86, 0), (113, 173),
    (168, 272), (5, 3), (0, 7), (168, 189), (168, 113), (113, 176), (0, 3), (0, 88), (0, 113)
]  # log10(multiple_times) = 25.6106868931126
Node2sSycamoreN53N20Test2 = [
    (32, 9), (360, 359), (13, 5), (3, 0), (358, 339), (43, 1), (362, 344), (372, 371), (367, 345), (375, 330),
    (366, 283), (380, 338), (379, 378), (363, 323), (117, 97), (294, 270), (37, 16), (84, 63), (150, 134), (319, 276),
    (276, 302), (76, 53), (312, 293), (245, 222), (234, 214), (115, 91), (177, 151), (332, 315), (228, 208), (51, 27),
    (189, 147), (218, 198), (198, 240), (72, 49), (135, 108), (103, 61), (61, 83), (61, 41), (50, 31), (213, 171),
    (326, 303), (210, 187), (299, 232), (200, 181), (286, 262), (9, 36), (143, 116), (348, 322), (333, 310), (310, 291),
    (304, 285), (343, 318), (347, 328), (370, 352), (219, 199), (275, 255), (178, 152), (296, 272), (57, 38), (54, 34),
    (153, 138), (138, 110), (185, 166), (300, 274), (274, 317), (48, 28), (28, 70), (30, 11), (162, 145), (204, 184),
    (21, 2), (309, 290), (114, 94), (227, 207), (23, 8), (179, 160), (160, 137), (137, 118), (100, 80), (80, 58),
    (279, 235), (122, 98), (233, 212), (212, 191), (127, 18), (376, 356), (182, 163), (220, 201), (197, 113),
    (252, 229), (104, 19), (237, 216), (248, 226), (226, 206), (45, 24), (24, 66), (123, 101), (211, 167), (89, 69),
    (297, 273), (60, 15), (68, 47), (159, 136), (368, 346), (292, 251), (165, 146), (62, 20), (20, 42), (176, 157),
    (93, 73), (26, 7), (107, 85), (112, 92), (337, 295), (295, 314), (278, 256), (269, 250), (180, 161), (109, 65),
    (148, 128), (128, 170), (154, 131), (111, 88), (238, 217), (246, 224), (156, 133), (133, 175), (334, 311), (25, 6),
    (209, 164), (223, 203), (44, 22), (12, 4), (306, 287), (287, 329), (349, 307), (331, 308), (373, 351), (361, 342),
    (261, 241), (52, 33), (321, 305), (149, 132), (132, 106), (225, 205), (288, 264), (120, 96), (303, 345), (374, 355),
    (244, 202), (155, 140), (99, 79), (67, 46), (192, 173), (324, 301), (263, 243), (243, 221), (289, 268), (188, 169),
    (257, 236), (336, 313), (193, 174), (280, 260), (59, 39), (39, 81), (335, 316), (231, 168), (95, 75), (259, 239),
    (126, 102), (341, 320), (90, 71), (77, 55), (316, 339), (215, 194), (267, 247), (40, 17), (354, 327), (340, 298),
    (144, 119), (377, 357), (281, 258), (365, 364), (86, 64), (78, 56), (29, 10), (307, 330), (323, 350), (221, 201),
    (47, 69), (239, 217), (290, 315), (140, 163), (140, 121), (301, 318), (75, 53), (320, 232), (136, 152), (169, 146),
    (161, 110), (157, 134), (313, 270), (55, 97), (56, 9), (247, 205), (287, 322), (71, 28), (202, 222), (58, 38),
    (311, 251), (20, 63), (305, 328), (194, 236), (18, 41), (73, 27), (85, 105), (167, 253), (102, 124), (16, 14),
    (46, 87), (268, 265), (295, 271), (171, 190), (264, 284), (131, 139), (174, 196), (206, 249), (191, 254),
    (133, 141), (164, 183), (187, 230), (166, 158), (173, 172), (352, 369), (39, 82), (119, 125), (33, 74), (4, 35),
    (316, 273), (323, 308), (64, 1), (357, 378), (287, 235), (194, 216), (194, 195), (53, 34), (158, 116), (46, 24),
    (187, 229), (205, 224), (205, 266), (20, 2), (217, 113), (131, 88), (206, 207), (38, 79), (27, 31), (167, 168),
    (39, 101), (133, 94), (18, 17), (301, 298), (171, 129), (352, 325), (134, 142), (164, 186), (201, 242), (327, 285),
    (273, 293), (308, 260), (357, 356), (1, 22), (264, 307), (28, 5), (271, 338), (206, 250), (201, 262), (187, 272),
    (298, 255), (116, 108), (27, 8), (325, 291), (24, 6), (194, 277), (113, 282), (134, 91), (119, 110), (1, 65),
    (264, 353), (235, 283), (264, 303), (6, 10), (108, 151), (108, 130), (206, 208), (260, 371), (17, 14), (205, 203),
    (34, 11), (38, 96), (5, 49), (203, 184), (235, 344), (1, 0), (194, 258), (235, 364), (206, 265), (260, 198),
    (14, 15), (38, 98), (5, 92), (198, 241), (0, 106), (184, 202), (194, 256), (198, 199), (0, 2), (0, 19), (235, 214),
    (14, 146), (206, 270), (38, 145), (5, 9), (0, 85), (14, 39), (194, 274), (184, 181), (5, 33), (0, 128), (14, 102),
    (198, 118), (214, 276), (0, 147), (214, 359), (194, 305), (214, 342), (118, 264), (14, 7), (118, 346), (118, 251),
    (214, 355), (7, 4), (214, 291), (214, 351), (214, 255), (4, 38), (214, 113), (4, 55), (113, 174), (113, 194),
    (4, 11), (4, 8), (113, 201), (113, 290), (4, 47), (113, 136), (113, 232), (113, 191), (113, 172), (113, 129),
    (4, 121), (4, 5), (4, 6), (4, 110), (4, 167), (4, 94), (4, 164), (4, 88), (4, 91), (4, 0), (0, 108), (0, 187),
    (0, 113), (0, 181), (0, 206), (0, 118), (0, 356), (0, 271), (0, 273), (0, 285)
]  # log10(multiple_times) = 25.888611588740623

EdgeSortStrH2OSycamoreN12M14 = """
[22 96 78 74 84 92 87 72 45 57 94 91 89 24 26  8  2 73  0 23 35 76 97  7 36 14 59 19 75 21  4 63 12 66 10  3 30 20 80 34
 90  6 52 11 77 79 53 31 16 49 54 25 70 62 56 33 83 95 15 18 47 43 93  9 55 71 32 29 64 46 67 17 44 38 86 61 13 40 51 58
 65 85 37 41 5 81 28 27 68 39 48 42  1 82 60 88 69 98 50]
"""
EdgeSortStrH2OSycamoreN53M12 = """
[263 165 127 209 233 160  88 291 344 207 269 128 396 124 397 161 388 125 266  73  56 155   5  81  26  80  98 346 340 323
  95  59 384 158   0 258 292 222 308  34 210  71  55 300 283 275 332 315 409 206 316 110  38   2  35 144 117 173  15 247
 195  37 257 244 135 309 302 162 113 120 331  16 121 134  12 142 212 343 261 153  72 299 141 400 339 150 208  46  40  52
 274 129  43 259  51 152  68 221  50 306 236  60 362 183 237 268 307 321 136  65 119 118 354 370 177 232  83 298  92  45
 360 199 350 218  17   1  89  96 231  49 172 336 166  20 369  94 159 337 107  84  28 187 241 196 372 239  82 289 131 198
 216 408  36 228 282 382 361 205 102 356 191 189 193  57 334 278 293 304 277 320  29 280 279  93 103 227 248 140 287 168
 32 355 380 254 174 170   13 403 281 214  19 229  63 371 410 246 352 224 353 303 378 157 333 376 325  76  97 167 116 171
 264 178   4 391 138  75 115   9 347  66 411  18 201 357 181 285 146 367 290 245  53  14 330 179 345 390 130 256 203 175
 101 106 392 255 365 385 329 322  47 348 311 194 393 211 251 250  10 226  54 412 133 375  23 260 123 137 200 399 267 328
 358 111 149 413 122 284  86 318 402 310 295 169 294 317 270 253 230  62  87 374 319 406 394 381 405 148 100 108  22 338
 342 234 252  61 114  77  30  41   8 176 276 197 147  58 297   3 154 180  69 364 265  39 182 217 164 126 215  25 373  24
 312 225 313 213 262 407  33 220  67 202 386 351  70 249  74 104  48  21 143  78 314 335 395 272 341 151 238 184 190  90
 286 223 271 398 188  64 163 377 240  79 109 112  99 366 349 379 145 105  44 389 192 359 324 186 301 273 326  42 383 401
 132 288  11   6 243 242  85  27 404 363 204 296 368 387 185   7  31 327 235 219 139 156 305  91]
"""
EdgeSortStrH2OSycamoreN53M14 = """
[445  85  19  49 133  17  95 140   4 216 441 434 320 457 272 289 475 427 259 126 221  48 127  92  86 229 197 470 483
 407 260 116 354 310  40 377  60 149 306 442 378  68 430 348 344  32 452 390 258 312 227 297 218 352 307 161  46 202
 194 135  43 300 308 478 295 178 365 425  72 112 179 388 162  47 422 443  96 186 305 293 410 326 262 339   0 459 255
 137 141 153 219 154 109 181 471 228  12 236 423  63 249 263  52 192  13 184  33  36  78 429  16 108 444 476  57 317
 271 129 436 404 264  55 405  56  74  91 146 177 125 455 217 118 187 424   2  99 150 274 107 460 253 298 389 171 353
  24 472 292  93 473 342 188 180  53 416 311 222  97 355  73 169 346  61 128 409  77 376 433 463 174 421 155 418 270
  14 435 234 195 235  98  90 176 119 357 438 175 428 294 208 351  54 115 393 120 166 261  94 299 134 143 230 124 469
 462 324  25 479  15 384 101 329 420  30  18 304  80 447 233 408 139 193 145 316 301 347 220 466  88  82 335 431   1
 415 419  27 382 163 100  28 268  50   3  34 212 231 132  67 242  44 314 448 383 122 396 103 276 224 102 361  76 437
  62 451 391 461 136 458 156 394 191 159 239 160 254 164  45 189 144 111 245  64 303 243 331 282 333 464 474 148 373
 467 414 157 277 392  79 321 213  22 401 232 205 267 395 440 142 170 319 403 360 340 456 426  59 323 413 291  75 362
  84 454 110  65 121 345 240 190 225 172  31 158 343 356  26 432 211 105 257 199 371  66 296 251 265 302 417  70  23
 114  42 341 123  51  37 131  20 398 247 397 370 465 183 334 363 283 381 453 374 385  38 185   8 288 325 315 446 482
 359 364 367  71 226 200 256  58  41  39  21 318 368 468   7 309 439 412   5 400 337 214 152 223 481 106 198 278 210
 281 290 402 275 206   6 113 449 330 204   9 372 406 285 480 375 237 151 167 284  69 387 269 279 273 266 477 369 117
 165 379 147  81 104 332  10 173 450 241 411 203 399 358  29  83 207 168 336 248 201 215 182 313 130 252 338 138 350
 246 196 327 287 328 250 349 244 286  35 322 238  87 209  11 366  89 280 386 380]
"""
EdgeSortStrH2OSycamoreN53M16 = """
[ 12  69 231 397 392 268 576  28 477 195 266 393 570 391  14 340 333 559 367 418 419 139 543  47 304   9 514 429 155
 439 158 152 553  45 560 129 486 556 188 101 416 535 575 498 551  15 504 124 580 321 156  91 177 371 554  72 121 166
 577 395 487 545  39 345  86 409 136 516 202 460 422 567 306 447 217 509 118 544 273 502 434 561  59 281 285 548 402
 364 322 491 334 414 473 494 119 113 542 381 465   5 483 305 518 270 448  46 503 342 350 203 496 566 573 534 383 138
 541 260 470 198 480 240  34 525 555 165 303 579 493 572 537 110 201  36 415 578 445 299 581 412 478 583 111 249 427
  84 511  16 313 248 168 479  18  10 550 469 222 436 505   1 160 265 557 507 225 360 302 289 378 571 183 115  89 146
 510  73 489 108 399 435 209 425 344 193 584 157 454 423  87 182 175 403 247 574 552 547 314 453 223  98  56 387  50
 290 320 512 170  20 134 328 404 236  23 295 234 428 324 251 140 291 259 294 528 329 292 267 354 457 122  11 382 262
 369 208 452 521 224  60 533 463 229 476 374 173 300 524 242 366 315 215 243 159 472 196 269 471 449 287  27  92 440
  53 216 286 351 370 438 353 441 357 325 197 191 563 130 390 330 501  76 406 145  63  58 417 176 327  79 218  13  95
 539 317  62  90 274   0  43 426 297 380 169 464 279 220 379  96 213 163 513 458 181 227 272 482 356 257 254 326 141
 190 278  80 481 132 398 459 373 385 123 421 362 348 347 275 411  48 310 400  93  41  97 517 150 396  74 312 245 443
 408 241 125 239  85 131 205 432 311 582 137  71 526 346 226 244 184 401 319 214 135 558 282 102  83  49 186 104  94
 180 128  31  37 343 109 405  51 204 532 256 475  54 171 519 529 430 250 298 413  75 280 112 336 468 359 309 189 221
 410   7 161 258  38 232 538 568 271  78 361  82 149  64 151  19 376 335 253 133 126   3 219 499 523   4  22 164  55
   6 308 337 237 143 207 536 365 349 338 252  32 105 355 332 194  66   8 114 284  21 144 444 530 261 167  52 106 339
 307  35 462 148 467 283 549 433 187  33 446 263 497  44 495 527  88 116 485 162 255 368 200 352 127 384 117 238 461
  65  61 288 103 488 437 424 569 147 178 185  17 500 301 420 199 431  70 331 323 564  67  57  30 233 562 296   2 490
 389 375 316 515 456 506 455  42 531 363 546 142 230 474 492 318  77 212 179 246 358  68 341 192 276 228 100  81 565
  24 484 153 451 442 372  40 394 377 508 210 206 293  25 174 172 235 466 388 450 264 107  99 120 211 386 520  29 154
 407 522 277 540  26]
"""
EdgeSortStrH2OSycamoreN53M18 = """
[308  47 362 144 388 273  80 128 427 165  95 167 482 471  22 100 324 274 271 473 183  82 319 123 226 266 463 268 435
 394 117  58  28 245 190  54 365  25 179 262 264 221 136 265 154 224 419 320 480 189 405  71 408 267 275 181 428  16
 223 433 301 209 398  97 231 222 184 287 282 479 339 392  23 272  55 443 312 315 146 211 470 180 432  67 393 260  52
 455 172 237 326 188 449 299  86  92 475 317  57 139  21 415 384 150  42 195 305 242 175 353 306  50 459 112  94 297
  13  51 446 256 437 114 166  26 140 101 283 425 255  60 132  90 177 307  56 174 403  83 378 292 158  10 151 286 289
 169  89 321 208  63 122 280 401 258 102  48 168 113 110  84 295 481 278 133 421  96  40 316 469 402 161 347  27 460
 410 182 413 138 127   2 400 259 163 436 430 103  75 457 279 417 194 422 250 106 472 483 109 228 309 234 131 424 288
 444 241 350 420 396 454 121  14 376 120 412 263 356  19 141 240 135 124 390 171  73 108 220 313 196  24 229 218 215
 452  35 116 232 474 302 129 348 204 468  70 389   1   0 293 395  36 404 198  66 212 448 328 355 244 462 456 290 152
  34 411 197 253 149 119 105 159   4 323 291 219 351 416 160 137 254  43  59 300  74 310 372 467 385  31 269 464  29
 445  45  77  17 466  93 270 431 330 458  33 199 381 153 251 235 342 447 477 143  39  38 357 277 318 441 434  11 377
 374  99 147 217 107 202 227 380 200 337   5 406 338 322 439 111 386  85 201 176 205  69 409 246 354 429 366  44 236
 451  68  61 249 164 407 371 115 358 162 261 187  37 373 367 284 329 303 142 450 118 397 453  65 252  62 248 130 156
 281 352 207 368 185 344 391 426 345  32 298 225  15   9  18 230 173   7 311 285 233 333 314  46 178 243  79 442 104
  41 438 346 155 247 257 340 238 461 145  20 440 327 206 465 186  87 157 375 325 349 125  12 203 336  53 134  49  81
 387  98  30 360  88   8 476 418 399 126 478 214 170 361 359  78  72  64  91 210 414 332   3 296 364 216 276 331   6
 304 334 343  76 239 341 148 335 363 423 382 192 213 191 379 383 294 370]
"""
EdgeSortStrH2OSycamoreN53M20 = """
[699 751 622 397  41 274 198 135 317   6 752  83 734 712 648  85 624 232 165 407 500  36 424  80 649 263 283 182 589
 442 316 113 741 744 602 271 170 434 130 150 749 646 412 394 679 264 655 306  49 410 213 614 676 663 323 579 324 163
 297 127 302 583 106 125 117 325 169 715  75 721 102 147 640 727  66  56  29 321 477  99  45 402 391 634  59 300 191
 703 209 666 732 613 695 293 706 689 670 435 608 582 122 700 654 664 735 745 307 298 299 201 400 415  22  18 617 136
 194  94 458 632 243 341 625 517  84 116 348 174 340  21 440  81 447 588 105 160 473 269 678 379  58 502 707 157 604
 312 698 738 651 328 563 562 609  51 650 643 188 510  47  14 258   7 577 710  88 492 133  55 683   4 123  78  24 743
 204 267 495 375 513 226 168 315 638 702  27 730 724  67 694 257 685  87 310 748  71   3 559 635 708  89  95 418  52
 736 211 202 110 395 111 665 368 282 284 172  43 523  34 633  70 594 581  13 626 112 486 190 716  33 153 641 161 309
 290  44 587 210 680 207 451 499 503 668 692 728 720 479 200  76  16 675 184 470 644  42 138 414 629 742 652 669 454
 506 630  73  90  82 146 275 171 430 301 584 327 733 409  32 636 631 717 158 289 140  25 677 192 313 627 688  11 288
 448  28 444 682 591 251 463 511 747 548 537  74 599 195  26 272 472 238 560 344 266 580 571  15 129 681 496 305  79
 637 249 388 308 701 119 605 326  19 661 250 164 508 658 351 381 515 569 714  62 319 142 731 466 177 693  63 573 203
 233 255 671 109 533 705 601 436 645  30 118  23 216 181  31 152 476 556 229 485 219   8 718 176 575 518  68 697 141
 156 199 279 273 722 482 471 552 144 162 320 687 115 719 711 483 490  92 336  86 468 349 103 597 107 489 459 521 148
   5 426 555 223 244 342 386 667 621 246 139 208 276 224 314 558 143 531 539  38 189 598 132 358 120 690  72 464 527
 166 423  10 303 493 740  77 595 265 592 373 474 673 205 750 101 215 361  35 217 350 704 242 524 175 227 514 653 509
 366 230  91 252 541 505 352 662 357 408 159 557 439 516 691 660 603 231 353 546  54   0 338  98 709 498 615 359 270
 610  20 333 234 128 425 206 237 185 218 540 280 456 628 453 241  64 295 296 642 657 121 173 235 481 108 405 519  61
 543 544 331 561 696 145 542 639 619 285  40 183 475 245 339 545 104 329 240 318 494 196 384  12 620 154 239 529 187
 593 330 100 739 504  60 590 335 428  48 737 550 607  96 332 432 225 566 528 337 374 443 403 612 429 686  53 467 364
 446 600 311 383  57 260 452 256 491 304 362 365 179 360 382 659 278  37 268 411 212 478 564 291 578 281 572 134 532
 221 554 387 220 149 370 497 520 398 393 488 616 363 536 726 512 248 114 420 417 585 576 356 389 487 262 647 437 469
 413 406 322 247 178 623 480 606 551 567 222 431 684 377 723 261 460   1 674 725 534 465 180 277 729 507 422 286 753
 433 713 746 197 254 253 445 421 124 462  97 186 565  93 354 570 347 167   2 596 372 346  39 380 399 392 401 343 151
  17 568 441  65 549   9 427 419 526  69 376 547 501 450 618 672  50 126 287 656 294 461 455 611  46 404 385 525 155
 228 355 586 438 538 553 131 259 416 396 371 574 214 449 193 367 535 236 334 390 530 345 457 522 292 484 369 378 137]
"""

StrSycamoreN12M14 = """
ORC0WXGSaP2kR31O4XI5vicBFbwjAewRA751SEKgqQUK9Wtfhsd4ZciCbbBEFhxUUKYqKawsYini69vSJG4g46FOdX11gTh66RjeCG05iEkHAtIof$Q
"""  # 5.5487431968520582
StrSycamoreN53M20 = """
98ArIppeSMhPZ8GwaY56Jt8TpJ$5SbnYFGS8HZf5Z6fT12Qf5f4UJC503PL9bLTmGeC1T3ZUi429FiEHayFOIb0V8g562IpWRETq3BI4L1TAUepgJW2RZfiI
xeM_Dex7v6uFarI55AjKJNPGp6mBeaBBhUTNE7eu3hjfUJ0EKNm1Km5fvkueQK12nHZS1wWgNr1pmDXFRhO9M1IInAahAniLxFmVn43sgYYJKho$0vZ4NXgS
5s14dKDOHtHz9uuwOLO$JiD0YPsV_fHhAwdfuTSzL_L9Sch0qJP_5QPJaXCPo4k8iYIFctZ_kfnWhOgHvE6PDw_Ya1YpiHQ5Pey7ArEz9rSFAGrR1XNKqI_R
91XHOQVQ_i57gjvwpC4ILN0_xIfIbMas8E1noVL79AEwaZDSkYxOUEE6TLHcmIen_IZfMlNWhaKJ9LE3LbDMHKme64axPnPg5IM2f4G0LNAN4shFE5Qrae0l
bFAQ8rYhfOuyXmTpn8XJhlQQNL1JbmhJKaDQTZE9K_MbcAjCYjdQIWw5jhHYmqL2m2CI0kKT8K3482UiXy3SRYxk2g1F3wIt1TifO9guO78Yva6UN0Zh7b9k
gMUHTMsULs1iGcncqdgYctY9CcXcHghcQcy6oQo0fzT4B8PkM9diU9dvZVrhY6dIPsdNDWoz1fU6HcqnLq9IpLtAHaq1js48ePUiN5eu2vojmdt_SCnpKOs9
tpSyGNU4mTbgOOSm$8r5IyesXhiOTXJJccp8qgPNZMQ9z80WuJZ4j2AdJ2_r1xanGfgDyYnvZsMm74Ojuh0LxseOuA2mfnZxLZToKVj4qZPQMM9heEN43RDl
9pGKTJ2bcec8UvcJANmQ3jHD0e_QEC6MV2OdMcvceMWQTqCievcIRL2YHUrlPVRYrXggbnqH2qWRnW5NvNWLnAxDo2xIVoKPyk47KnfbR0JkcRwdKDBeR0Hk
JxKs0uO6sSP94SRp3Gj6ZT3gEOnWWT2gHINc$bMk4GjiZtng00XbZyN8WJfeB982Y0oTyHOUXs5wXVOc0L1cBAyj_G18hyjRN25W0Z9PHAJ28_fG6HYKI9Du
NCDi7dxD6GZfCyCQQ6cKo2UYh0becBmxTAv1u9KMtt51wmvdjRXJ2ad1XUOCqYi8jXUKeMBdRjhM_B6DM1d_10WgycGkYrsJEG_7vMM0GB87400sHX1g41zV
mmUbPtw3mYa$0eMOacP94jVYMeLe8_AG9ij9Kc0ufXBW9dLcWE4ZNfr2W
"""  # 18.4874470951132253


def get_nodes_list_and_band_edges_of_tensor_ring(len_list: int = 4):
    ban_edges = len_list

    nodes = [[] for _ in range(len_list)]  # 初始化邻接表
    for i in range(len_list):
        nodes[i].append((i - 1) % len_list)
        nodes[i].append((i + 1) % len_list)

        nodes[i].append(i + len_list)
        nodes.append([i])
    return nodes, ban_edges


def get_nodes_list_and_band_edges_of_tensor_train(len_list: int = 4):
    ban_edges = len_list

    nodes = [[] for _ in range(len_list)]  # 初始化邻接表
    for i in range(len_list):
        if i > 0:
            nodes[i].append(i - 1)
        if i < len_list - 1:
            nodes[i].append(i + 1)
        nodes[i].append(i + len_list)
        nodes.append([i])
    return nodes, ban_edges


def get_nodes_list_and_ban_edges_of_tensor_tree(depth: int = 3):
    depth -= 1

    # 初始化二叉树的二维列表
    num_nodes = 2 ** (depth + 1) - 1
    ban_edges = 2 ** depth
    tree = [[] for _ in range(num_nodes)]

    # 添加二叉树的边
    def add_edges(_depth, node=0, org_node=-1):
        left_node = node * 2 + 1
        right_node = node * 2 + 2

        tree[node].append(org_node) if org_node >= 0 else None
        if _depth == 0:
            return
        tree[node].append(left_node)
        tree[node].append(right_node)

        org_node = node
        _depth -= 1
        add_edges(_depth, left_node, org_node)
        add_edges(_depth, right_node, org_node)

    add_edges(depth)
    return tree, ban_edges


def get_nodes_ary(nodes_list: list) -> TEN:
    # nodes_list = NodesSycamore
    nodes_ary = th.zeros((len(nodes_list), max([len(nodes) for nodes in nodes_list])), dtype=th.int) - 1
    # # -1 表示这里没有连接
    for i, nodes in enumerate(nodes_list):
        for j, node in enumerate(nodes):
            nodes_ary[i, j] = node
    return nodes_ary


def get_edges_ary(nodes_ary: TEN) -> TEN:
    edges_ary = th.zeros_like(nodes_ary, dtype=nodes_ary.dtype)
    edges_ary[nodes_ary >= 0] = -2  # -2 表示这里的 edge_i 需要被重新赋值
    edges_ary[nodes_ary == -1] = -1  # -1 表示这里的 node 没有连接另一个 node

    num_edges = 0
    '''get nodes_ary'''
    # for i, nodes in enumerate(nodes_ary):  # i 表示节点的编号
    #     for j, node in enumerate(nodes):  # node 表示跟编号为i的节点相连的另一个节点
    #         edge_i = edges_ary[i, j]
    #         if edge_i == -2:
    #             _j = th.where(nodes_ary[node] == i)
    #             edges_ary[i, j] = num_edges
    #             edges_ary[node, _j] = num_edges
    #             num_edges += 1
    '''get nodes_ary and sort the ban edges to large indices'''
    for i, nodes in list(enumerate(nodes_ary))[::-1]:  # i 表示节点的编号
        for j, node in enumerate(nodes):  # node 表示跟编号为i的节点相连的另一个节点
            edge_i = edges_ary[i, j]
            if edge_i == -2:
                nodes_ary_node: TEN = nodes_ary[node]
                _j = th.where(th.eq(nodes_ary_node, i))

                edges_ary[i, j] = num_edges
                edges_ary[node, _j] = num_edges
                num_edges += 1
    _edges_ary = edges_ary.max() - edges_ary
    _edges_ary[edges_ary == -1] = -1
    edges_ary = _edges_ary
    return edges_ary


def get_node_dims_arys(nodes_ary: TEN) -> list:
    num_nodes = nodes_ary.shape[0]

    arys = []
    for nodes in nodes_ary:
        positive_nodes = nodes[nodes >= 0].long()
        ary = th.zeros((num_nodes,), dtype=th.int)  # 因为都是2，所以我用0 表示 2**0==1
        ary[positive_nodes] = 1  # 2量子比特门，这里的计算会带来2个单位的乘法，因为都是2，所以我用1 表示 2**1==2
        arys.append(ary)
    return arys


def get_node_bool_arys(nodes_ary: TEN) -> list:
    num_nodes = nodes_ary.shape[0]

    arys = []
    for i, nodes in enumerate(nodes_ary):
        ary = th.zeros((num_nodes,), dtype=th.bool)
        ary[i] = True
        arys.append(ary)
    return arys


class SimulatorTensorNetContract:
    def __init__(self, nodes_list: list, ban_edges: int, device: th.device, if_vec: bool = True):
        self.device = device

        '''build node_arys and edges_ary'''
        nodes_ary = get_nodes_ary(nodes_list)
        num_nodes = nodes_ary.max().item() + 1
        assert num_nodes == nodes_ary.shape[0]

        edges_ary = get_edges_ary(nodes_ary)
        num_edges = edges_ary.max().item() + 1
        assert num_edges == th.ne(edges_ary, -1).sum() / 2

        self.nodes_ary = nodes_ary
        self.edges_ary = edges_ary.to(device)
        self.num_nodes = num_nodes
        self.num_edges = num_edges
        self.ban_edges = ban_edges

        '''build for get_log10_multiple_times'''
        node_dims_arys = get_node_dims_arys(nodes_ary)
        assert num_edges == sum([(ary == 1).sum().item() for ary in node_dims_arys]) / 2

        node_bool_arys = get_node_bool_arys(nodes_ary)
        assert num_nodes == sum([ary.sum() for ary in node_bool_arys])

        self.dims_ten = th.stack(node_dims_arys).type(th.float32).to(device)
        self.bool_ten = th.stack(node_bool_arys).type(th.bool).to(device)
        default_num_envs = 1
        self.dims_tens = th.stack([self.dims_ten.clone() for _ in range(default_num_envs)])
        self.bool_tens = th.stack([self.bool_ten.clone() for _ in range(default_num_envs)])

        self.update_pow_counts = self.update_pow_vectorized if if_vec else self.update_pow_vanilla

        '''build for binary search'''
        num_bases = math.ceil(math.log2(num_edges))
        self.num_bits = num_edges * num_bases
        self.num_bases = num_bases
        self.base_numbers = th.tensor([2 ** i for i in range(num_bases - 1, -1, -1)], device=device)[None, None, :]

    def get_log10_multiple_times(self, edge_sorts: TEN, if_acc: bool = False) -> TEN:
        # edge_argsort = th.rand(self.num_edges).argsort()
        device = self.device
        edges_ary: TEN = self.edges_ary
        num_envs, run_edges = edge_sorts.shape

        if not (self.dims_tens.shape[0] == self.bool_tens.shape[0] == num_envs):
            self.dims_tens = th.stack([self.dims_ten.clone() for _ in range(num_envs)])
            self.bool_tens = th.stack([self.bool_ten.clone() for _ in range(num_envs)])
        dims_tens = self.dims_tens.clone()
        bool_tens = self.bool_tens.clone()

        pow_counts = th.zeros((num_envs, run_edges), dtype=th.float64, device=device)
        for i in range(run_edges):
            edge_is = edge_sorts[:, i]
            self.update_pow_counts(i, edge_is, edges_ary, dims_tens, bool_tens, pow_counts)

        # pow_counts += 1  # todo WARMING (Maybe opt_einsum is wrong)
        result = self.get_multiple_times_vectorized(pow_counts) if if_acc \
            else self.get_multiple_times_accurately(pow_counts)
        return result.detach()

    @staticmethod
    def update_pow_vanilla(i: int, edge_is: TEN, edges_ary: TEN,
                           dims_tens: TEN, bool_tens: TEN, pow_counts: TEN):
        num_envs = pow_counts.shape[0]

        for j in range(num_envs):
            edge_i = edge_is[j]
            dims_arys = dims_tens[j]
            bool_arys = bool_tens[j]

            '''find two nodes of an edge_i'''
            node_i0, node_i1 = th.where(th.eq(edges_ary, edge_i))[0]  # 找出这条edge 两端的node
            # assert isinstance(node_i0.item(), int)
            # assert isinstance(node_i1.item(), int)

            '''whether node_i0 and node_i1 are different'''
            if_diff = th.logical_not(bool_arys[node_i0, node_i1])

            '''calculate the multiple and avoid repeat'''
            ct_dims = dims_arys[node_i0] + dims_arys[node_i1] * if_diff  # 计算收缩后的node 的邻接张量的维数以及来源
            ct_bool = bool_arys[node_i0] | bool_arys[node_i1]  # 计算收缩后的node 由哪些原初node 合成
            # assert ct_dims.shape == (num_nodes, )
            # assert ct_bool.shape == (num_nodes, )

            # 收缩掉的edge 只需要算一遍乘法。因此上面对 两次重复的指数求和后乘以0.5
            pow_count = ct_dims.sum(dim=0) - (ct_dims * ct_bool).sum(dim=0) * 0.5
            pow_counts[j, i] = pow_count * if_diff

            '''adjust two list: dims_arys, bool_arys'''
            # 如果两个张量是一样的，那么 `ct_bool & if_diff` 就会全部变成 False，让下面这行代码不修改任何数值
            ct_dims[ct_bool & if_diff] = 0  # 把收缩掉的边的乘法数量赋值为2**0，接下来不再参与乘法次数的计算
            dims_tens[j, ct_bool] = ct_dims.repeat(1, 1)  # 根据 bool 将所有收缩后的节点都刷新成相同的信息
            bool_tens[j, ct_bool] = ct_bool.repeat(1, 1)  # 根据 bool 将所有收缩后的节点都刷新成相同的信息

    @staticmethod
    def update_pow_vectorized(i: int, edge_is: TEN, edges_ary: TEN,
                              dims_tens: TEN, bool_tens: TEN, pow_counts: TEN):
        num_sims = pow_counts.shape[0]
        env_is = th.arange(num_sims, device=pow_counts.device)

        '''find two nodes of an edge_i'''
        vec_edges_ary: TEN = edges_ary[None, :, :]
        vec_edges_is: TEN = edge_is[:, None, None]
        res = th.where(th.eq(vec_edges_ary, vec_edges_is))[1]
        res = res.reshape((num_sims, 2))
        node_i0s, node_i1s = res[:, 0], res[:, 1]
        # assert node_i0s.shape == (num_sims, )
        # assert node_i1s.shape == (num_sims, )

        '''whether node_i0 and node_i1 are different'''
        if_diffs = th.logical_not(bool_tens[env_is, node_i0s, node_i1s])
        # assert if_diffs.shape == (num_sims, )

        '''calculate the multiple and avoid repeat'''
        ct_dimss = dims_tens[env_is, node_i0s] + dims_tens[env_is, node_i1s] * if_diffs.unsqueeze(1)
        ct_bools = bool_tens[env_is, node_i0s] | bool_tens[env_is, node_i1s]
        # assert ct_dimss.shape == (num_sims, num_nodes)
        # assert ct_bools.shape == (num_sims, num_nodes)

        # 初始化的时候，给每个节点它自己多送了一个 2 ** 1 标记，排除重复的乘法时，会多减了它自己，下面的代码把它加回去
        pow_count = ct_dimss.sum(dim=1) - (ct_dimss * ct_bools).sum(dim=1) * 0.5
        pow_counts[:, i] = pow_count * if_diffs

        '''adjust two list: dims_arys, bool_arys'''
        j_list = [j for j in range(num_sims) if if_diffs[j]]  # todo 跳过已经被收缩过的边
        for j in j_list:  # 根据 bool 将所有收缩后的节点都刷新成相同的信息
            ct_dims = ct_dimss[j]
            ct_bool = ct_bools[j]

            ct_dims[ct_bool] = 0  # 把收缩掉的边的乘法数量赋值为2**0，接下来不再参与乘法次数的计算
            dims_tens[j, ct_bool] = ct_dims[None, :]
            bool_tens[j, ct_bool] = ct_bool[None, :]

    def get_multiple_times_accurately(self, pow_times: TEN) -> TEN:
        num_envs = pow_times.shape[0]
        # 缓慢但是完全不损失精度的计算方法
        multiple_times = []
        pow_times = pow_times.cpu().numpy()
        for env_id in range(num_envs):
            multiple_time = 0
            for pow_time in pow_times[env_id, :]:
                multiple_time = multiple_time + 2 ** pow_time
            multiple_time = math.log10(multiple_time)
            multiple_times.append(multiple_time)
        return th.tensor(multiple_times, dtype=th.float64, device=self.device)

    def get_multiple_times_vectorized(self, pow_times: TEN) -> TEN:
        # 快速，但是有效数值有 1e-7 的计算方法（以下都是 float64）
        adj_pow_times = pow_times.max(dim=1)[0] - 960  # automatically set `max - 960`, 960 < the limit 1024
        # 计算这个乘法个数时，即便用 float64 也偶尔会过拟合，所以先除以 2**temp_power ，求log10 后再恢复它
        multiple_times = (th.pow(2, pow_times - adj_pow_times.unsqueeze(1))).sum(dim=1)
        multiple_times = multiple_times.log10() + adj_pow_times / th.log2(th.tensor((10,), device=self.device))
        # adj_pow_times / th.log2(th.tensor((10, ), device=device))  # Change of Base Formula
        return multiple_times

    def convert_edge_sort_to_node2s(self, edge_sort: TEN) -> list:
        edges_ary: TEN = self.edges_ary.cpu()
        edge_sort = edge_sort.cpu()

        run_edges = edge_sort.shape[0]
        assert run_edges == self.num_edges - self.ban_edges

        node2s = []
        for i in range(run_edges):
            edge_i = edge_sort[i]

            '''find two nodes of an edge_i'''
            node_i0, node_i1 = th.where(th.eq(edges_ary, edge_i))[0]  # 找出这条edge 两端的node
            # assert isinstance(node_i0.item(), int)
            # assert isinstance(node_i1.item(), int)
            node2s.append((node_i0.item(), node_i1.item()))
        return node2s

    def convert_node2s_to_edge_sort(self, node2s: list) -> TEN:
        edges_ary: TEN = self.edges_ary.clone().cpu()
        # nodes_ary: TEN = self.nodes_ary.clone().cpu()

        edges_tmp = [set(edges.tolist()) for edges in edges_ary]
        for edges in edges_tmp:
            edges.discard(-1)

        edge_sort = []
        for node_i0, node_i1 in node2s:
            edge_i0_set = edges_tmp[node_i0]
            edge_i1_set = edges_tmp[node_i1]
            print(f"{node_i0:4} {str(edge_i0_set):17}    "
                  f"{node_i1:4} {str(edge_i1_set):17}    ")

            edge_is = edge_i0_set.intersection(edge_i1_set)
            edge_i = sorted(list(edge_is))[0]  # ordered
            #  edge_i = edge_is.pop()  # disordered
            edge_sort.append(edge_i)

            edge_01_set = edge_i0_set.union(edge_i1_set)
            edges_tmp[node_i0] = edge_01_set
            edges_tmp[node_i1] = edge_01_set

        edge_sort = th.tensor(edge_sort)
        return edge_sort

    def generate_xs_randomly(self, num_sims: int) -> TEN:
        edge_sorts = th.stack([th.randperm(self.num_edges, device=self.device)
                               for _ in range(num_sims)])
        xs = self.convert_edge_sorts_to_binary_xs(edge_sorts=edge_sorts)
        return xs

    def calculate_obj_values(self, xs: TEN, if_acc: bool = False) -> TEN:
        edge_sorts = self.convert_binary_xs_to_edge_sorts(xs=xs)
        log10_multiple_times = self.get_log10_multiple_times(edge_sorts=edge_sorts, if_acc=if_acc)
        return log10_multiple_times

    def convert_binary_xs_to_edge_sorts(self, xs):
        num_sims = xs.shape[0]

        xs_view = xs.view(num_sims, self.num_edges, self.num_bases)
        edge_ranks = (xs_view * self.base_numbers).sum(dim=2)
        edge_sorts = th.argsort(edge_ranks, dim=1)
        return edge_sorts

    def convert_edge_sorts_to_binary_xs(self, edge_sorts: TEN):
        num_sims = edge_sorts.shape[0]

        xs = th.empty((num_sims, self.num_bits), dtype=th.bool, device=self.device)
        for i in range(num_sims):
            edge_sort = edge_sorts[i]
            binary_string = [format(num, f'0{self.num_bases}b')
                             for num in self.matching_sort(edge_sort).cpu().data.numpy()]
            binary_tensor = [[int(bit) for bit in b] for b in binary_string]
            binary_tensor = th.tensor(binary_tensor, dtype=th.bool, device=self.device)
            x = binary_tensor.reshape(-1)
            xs[i] = x
        return xs

    def format_xs(self, xs):
        edge_sorts = self.convert_binary_xs_to_edge_sorts(xs)
        xs = self.convert_edge_sorts_to_binary_xs(edge_sorts)
        return xs

    @staticmethod
    def matching_sort(src_sort):
        indices = th.arange(src_sort.shape[0])
        dst_sort = th.zeros_like(indices)
        dst_sort[src_sort] = indices
        return dst_sort

    @staticmethod
    def matching_sorts(src_sorts):
        num_sims, num_edges = src_sorts.shape
        device = src_sorts.device

        dst_sorts = th.zeros_like(src_sorts)
        indices = th.arange(num_edges, device=device)
        for i in range(num_sims):
            src_sort = src_sorts[i]
            dst_sorts[i, src_sort] = indices
        return dst_sorts


def convert_str_ary_to_list_as_edge_sort(str_ary: str) -> list:
    str_ary = str_ary.replace('   ', ',').replace('  ', ',').replace(' ', ',').replace('[,', '[ ')
    return eval(str_ary)


'''unit tests'''


def unit_test_get_log10_multiple_times():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    # nodes_list, ban_edges = NodesSycamoreN12M14, 0
    # nodes_list, ban_edges = NodesSycamoreN14M14, 0
    # nodes_list, ban_edges = NodesSycamoreN53M12, 0
    nodes_list, ban_edges = get_nodes_list_and_band_edges_of_tensor_train(len_list=8)
    # nodes_list, ban_edges = get_nodes_list_of_tensor_train(len_list=100), 100
    # nodes_list, ban_edges = get_nodes_list_of_tensor_train(len_list=2000), 2000
    # from TNCO_env import get_nodes_list_of_tensor_tree
    # nodes_list, ban_edges = get_nodes_list_of_tensor_tree(depth=3), 2 ** (3 - 1)

    env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
    print(f"\nnum_nodes      {env.num_nodes:9}"
          f"\nnum_edges      {env.num_edges:9}"
          f"\nban_edges      {env.ban_edges:9}")
    num_envs = 6

    # th.save(edge_arys, 'temp.pth')
    # edge_arys = th.load('temp.pth', map_location=device)

    edge_arys = th.rand((num_envs, env.num_edges - env.ban_edges), device=device)
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_arys.argsort(dim=1))
    print(f"multiple_times(log10) {multiple_times.cpu().numpy()}")

    edge_arys = th.rand((num_envs, env.num_edges - env.ban_edges), device=device)
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_arys.argsort(dim=1), if_acc=True)
    print(f"multiple_times(log10) if_vec=True  {multiple_times.cpu().numpy()}")
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_arys.argsort(dim=1), if_acc=False)
    print(f"multiple_times(log10) if_vec=False {multiple_times.cpu().numpy()}")


def unit_test_convert_node2s_to_edge_sorts():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    # nodes_list, ban_edges = NodesSycamoreN12M14, 0
    # nodes_list, ban_edges = NodesSycamoreN14M14, 0
    nodes_list, ban_edges = NodesSycamoreN53M12, 0
    # nodes_list, ban_edges = get_nodes_list_of_tensor_train(len_list=8), 8
    # nodes_list, ban_edges = get_nodes_list_of_tensor_train(len_list=100), 100
    # nodes_list, ban_edges = get_nodes_list_of_tensor_train(len_list=2000), 2000
    # from TNCO_env import get_nodes_list_of_tensor_tree
    # nodes_list, ban_edges = get_nodes_list_of_tensor_tree(depth=3), 2 ** (3 - 1)

    env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
    print(f"\nnum_nodes      {env.num_nodes:9}"
          f"\nnum_edges      {env.num_edges:9}"
          f"\nban_edges      {env.ban_edges:9}")
    num_envs = 6

    # th.save(edge_arys, 'temp.pth')
    # edge_arys = th.load('temp.pth', map_location=device)

    edge_arys = th.rand((num_envs, env.num_edges - env.ban_edges), device=device)
    edge_ary = edge_arys[0]
    print(edge_ary.argsort().shape)
    print(edge_ary.argsort())
    node2s = env.convert_edge_sort_to_node2s(edge_sort=edge_ary.argsort(dim=0))
    edge_sort = env.convert_node2s_to_edge_sort(node2s=node2s).to(device)
    print(edge_sort.shape)
    print(edge_sort)

    print(edge_sort - edge_ary.argsort())
    edge_sorts = edge_sort.unsqueeze(0)
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_sorts.to(device))
    print(f"multiple_times(log10) {multiple_times.cpu().numpy()}")


def unit_test_convert_node2s_to_edge_sorts_of_load():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    # nodes_list, ban_edges = NodesSycamoreN53M20, 0
    nodes_list, ban_edges = get_nodes_list_and_band_edges_of_tensor_train(len_list=100)
    env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
    print(f"\nnum_nodes      {env.num_nodes:9}"
          f"\nnum_edges      {env.num_edges:9}"
          f"\nban_edges      {env.ban_edges:9}")

    node2s, ground_true_log10 = Node2sSycamoreN53N20Test1, 25.6106868931126
    # node2s, ground_true_log10 = Node2sSycamoreN53N20Test2, 25.888611588740623
    edge_sort = env.convert_node2s_to_edge_sort(node2s=node2s).to(device)
    print(edge_sort.shape)
    print(edge_sort)

    edge_sorts = edge_sort.unsqueeze(0)
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_sorts.to(device), if_acc=True)
    multiple_times = multiple_times.cpu().numpy()[0]
    print(f"multiple_times(log10) {multiple_times:20.16f}    "
          f"diff (if_vec=True)    {multiple_times - ground_true_log10:9.3e}")
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_sorts.to(device), if_acc=False)
    multiple_times = multiple_times.cpu().numpy()[0]
    print(f"multiple_times(log10) {multiple_times:20.16f}    "
          f"diff (if_vec=False)   {multiple_times - ground_true_log10:9.3e}")


def unit_test_edge_sorts_to_log10_multiple_times():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    edge_sort_str = EdgeSortStrH2OSycamoreN12M14  # 5.5792907356870209, otherSOTA 5.83
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M12  # 14.7798258185512630, otherSOTA 12.869
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M14  # 15.2322678386901487, otherSOTA 14.420
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M16  # 19.8684635668356293, otherSOTA 17.012
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M18  # 23.7903614350502544, otherSOTA 17.484
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M20  # 21.1282464668655585, otherSOTA 18.544

    edge_sort = convert_str_ary_to_list_as_edge_sort(edge_sort_str)
    edge_sort = th.tensor(edge_sort, dtype=th.long).to(device)

    '''auto choose NodesSycamore'''
    num_edges = max(edge_sort) + 1
    nodes_list, ban_edges = None, 0
    for nodes_list in (
            NodesSycamoreN12M14, NodesSycamoreN14M14,
            NodesSycamoreN53M12, NodesSycamoreN53M14, NodesSycamoreN53M16, NodesSycamoreN53M18, NodesSycamoreN53M20,
    ):
        env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
        if num_edges == env.num_edges:
            break
    else:
        raise ValueError(f"num_edges {num_edges}")
    print(f"\nnum_nodes      {env.num_nodes:9}"
          f"\nnum_edges      {env.num_edges:9}"
          f"\nban_edges      {env.ban_edges:9}")

    '''get multiple_times'''
    edge_sorts = edge_sort.unsqueeze(0)
    multiple_times = env.get_log10_multiple_times(edge_sorts=edge_sorts.to(device), if_acc=False)
    multiple_times = multiple_times.cpu().numpy()[0]
    print(f"multiple_times(log10) {multiple_times:20.16f}")

    # import numpy as np
    # np.set_printoptions(linewidth=120)
    # print(edge_sort.cpu().numpy())


def unit_test_warm_up():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    warm_up_size = 2 ** 6  # 2 ** 14
    target_score = -th.inf  # 7.0
    """
    你可以选择 target_score = 负无穷，然后设置你想要的 warm_up_size ，直接测试仿真环境 并行与否 的耗时
    也可以选择 warm_up_size = 正无穷，然后设置你想要的 target_score ，直接测试仿真环境 并行与否 的耗时
    """
    if_vec = True  # 设置 if_vec = True。可以在有GPU的情况下，高效快速地并行计算乘法次数
    if_acc = True  # 设置 if_acc = True。这种设置虽然慢，但是它使用int计算，能非常精确且不溢出地算出结果（能避免nan）
    env_nums = 2 ** 2
    """
    在启用 if_vec = True 的情况下，你可以设置 env_nums 来主动设置并行子环境数量。
    越好的GPU，就可以设置越大的 env_nums，设置到 GPU使用率无法再提高的情况下，会得到一个接近最高性价比的 env_nums
    """

    # nodes_list, ban_edges = NodesSycamoreN12M14, 0
    # nodes_list, ban_edges = get_nodes_list_of_tensor_train(100), 100
    nodes_list, ban_edges = get_nodes_list_and_ban_edges_of_tensor_tree(depth=9)

    """
    这里你可以选择不同的张量电路无向图，在这里跑不同的任务。注意选择正确的 ban_edges 以及对应的 target_socre
    """

    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device, if_vec=if_vec)
    dim = env.num_edges - env.ban_edges

    min_score = th.inf

    from time import time as timer
    start_time = timer()
    for i in range(warm_up_size // env_nums):
        thetas = th.rand((env_nums, dim), dtype=th.float32, device=device)
        thetas = ((thetas - thetas.mean(dim=1, keepdim=True)) / (thetas.std(dim=1, keepdim=True) + 1e-6))

        scores = env.get_log10_multiple_times(edge_sorts=thetas.argsort(dim=1), if_acc=if_acc)
        min_score = min(scores.min(dim=0)[0].item(), min_score)
        print(f"MinScore {min_score:16.9f}  UsedTime {timer() - start_time:9.3f}  SearchNum {(i + 1) * env_nums:9.0f}")
        if min_score < target_score:
            break
    """
    min_score 是这一次 warm_up 搜索到的最优分数
    UsedTime 是开始训练到此刻的耗时
    SearchNum 是开始训练到此刻的搜索次数

    实验结果：
    nodes_list, ban_edges = get_nodes_list_of_tensor_train(100), 100
    if_acc = False

    if_vec = False       MinScore 30.404030  UsedTime   151.614  SearchNum      4096
    env_nums = 2 ** 2    MinScore 30.404030  UsedTime    79.989  SearchNum      4096
    env_nums = 2 ** 4    MinScore 30.404030  UsedTime    55.738  SearchNum      4096
    env_nums = 2 ** 8    MinScore 30.404030  UsedTime    52.963  SearchNum      4096
    env_nums = 2 ** 12   MinScore 30.404030  UsedTime    52.031  SearchNum      4096
    """


def check_env_calculate_obj_values():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    num_sims = 3

    edge_sort_str = EdgeSortStrH2OSycamoreN12M14  # 5.5792907356870209, otherSOTA 5.83
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M12  # 14.7798258185512630, otherSOTA 12.869
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M14  # 15.2322678386901487, otherSOTA 14.420
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M16  # 19.8684635668356293, otherSOTA 17.012
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M18  # 23.7903614350502544, otherSOTA 17.484
    # edge_sort_str = EdgeSortStrH2OSycamoreN53M20  # 21.1282464668655585, otherSOTA 18.544

    edge_sort = convert_str_ary_to_list_as_edge_sort(edge_sort_str)
    edge_sort = th.tensor(edge_sort, dtype=th.long).to(device)

    '''auto choose NodesSycamore'''
    num_edges = max(edge_sort) + 1
    nodes_list, ban_edges = None, 0
    for nodes_list in (
            NodesSycamoreN12M14, NodesSycamoreN14M14,
            NodesSycamoreN53M12, NodesSycamoreN53M14, NodesSycamoreN53M16, NodesSycamoreN53M18, NodesSycamoreN53M20,
    ):
        env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
        if num_edges == env.num_edges:
            break
    else:
        raise ValueError(f"num_edges {num_edges}")
    print(f"\nnum_nodes      {env.num_nodes:9}"
          f"\nnum_edges      {env.num_edges:9}"
          f"\nban_edges      {env.ban_edges:9}")

    xs = env.generate_xs_randomly(num_sims=num_sims)
    multiple_times = env.calculate_obj_values(xs=xs, if_acc=False)
    multiple_times = multiple_times.cpu().numpy()
    print(f"multiple_times(log10) {multiple_times}")


def check_format_xs():
    import sys
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    nodes_list, ban_edges = NodesSycamoreN53M20, 0
    edge_sort_str = EdgeSortStrH2OSycamoreN53M20  # 21.1282464668655585, otherSOTA 18.544

    edge_sort = convert_str_ary_to_list_as_edge_sort(edge_sort_str)
    edge_sort = th.tensor(edge_sort, dtype=th.long).to(device)

    '''auto choose NodesSycamore'''
    # env = TensorNetworkEnv(nodes_list=nodes_list, ban_edges=ban_edges, device=device, num_bases=-1)
    env = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
    print(f"\nnum_nodes      {env.num_nodes:9}"
          f"\nnum_edges      {env.num_edges:9}"
          f"\nban_edges      {env.ban_edges:9}")

    num_sims = 3
    xs = th.randint(2, (num_sims, env.num_bits), dtype=th.bool, device=device)
    vs = env.calculate_obj_values(xs=xs)
    print(f"| {vs.min().item():20.16f}  {vs.mean().item():20.16f}")
    xs = env.format_xs(xs)
    vs = env.calculate_obj_values(xs=xs)
    print(f"| {vs.min().item():20.16f}  {vs.mean().item():20.16f}")


def check_str_edge_sort():
    gpu_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    device = th.device(f'cuda:{gpu_id}' if th.cuda.is_available() and gpu_id >= 0 else 'cpu')

    # nodes_list, ban_edges = NodesSycamoreN53M20, 0
    # x_str = StrSycamoreN53M20
    nodes_list, ban_edges = NodesSycamoreN12M14, 0
    x_str = StrSycamoreN12M14

    sim = SimulatorTensorNetContract(nodes_list=nodes_list, ban_edges=ban_edges, device=device)
    print(f"\nnum_nodes      {sim.num_nodes:9}"
          f"\nnum_edges      {sim.num_edges:9}"
          f"\nban_edges      {sim.ban_edges:9}")

    from evaluator import EncoderBase64
    encoder_base64 = EncoderBase64(encode_len=sim.num_bits)
    x = encoder_base64.str_to_bool(x_str=x_str)
    edge_sorts = sim.convert_binary_xs_to_edge_sorts(xs=x[None, :])
    multiple_times = sim.get_log10_multiple_times(edge_sorts=edge_sorts, if_acc=True)
    multiple_times = multiple_times.item()
    print(f'multiple_times(log10) {multiple_times:20.16f}')


if __name__ == '__main__':
    # unit_test_get_log10_multiple_times()
    # unit_test_convert_node2s_to_edge_sorts()
    # unit_test_convert_node2s_to_edge_sorts_of_load()
    # unit_test_edge_sorts_to_log10_multiple_times()
    # unit_test_warm_up()
    check_str_edge_sort()
